
正文
rest-framework框架组件
提示:扫一扫查出行【扫一扫了解最新限行尾号】
复制提示
序列化组件
创建一个序列化类,
视图四种方式
以下代码都需要创建一个serializers.py文件
from rest_framework import serializers
from CBV_app.models import *
from CBV_app.urls import *
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model = Publish
# 排除id不显示,其余全部显示
exclude =("id", )
class AuthorSerializers(serializers.ModelSerializer):
class Meta:
model = Author
fields = "__all__"
class BookSerializers(serializers.ModelSerializer):
class Meta:
model=Book
fields="__all__"
urls除了方式四以外通用这种格式
-
这里必须得使用pk关键字参数,因为源码部分取的是pk值,如果不使用pk则找不到
from rest_framework import serializers
from CBV_app.models import *
from CBV_app.urls import *
class PublishSerializers(serializers.ModelSerializer):
class Meta:
model = Publish
# 排除id不显示,其余全部显示
exclude =("id", )
class AuthorSerializers(serializers.ModelSerializer):
class Meta:
model = Author
fields = "__all__"
class BookSerializers(serializers.ModelSerializer):
class Meta:
model=Book
fields="__all__"
方式一
- views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from CBV_app import models
from CBV_app.serializers import PublishSerializers,AuthorSerializers,BookSerializers
class PublishViews(APIView):
# 查看所有数据
def get(self, request):
publish_all = models.Publish.objects.all()
# 使用Django自带的序列化组件
# 发送给前端的为json格式的数据,需要前端自己反序列化
# from django.core.serializers import serialize
#
# res = serialize("json", publish_all)
#
# return HttpResponse(res)
# 使用rest序列化, many=True 返回的是QuerySet对象
ps = PublishSerializers(publish_all, many=True)
# ps.data序列化数据
return Response(ps.data)
# 添加数据
def post(self, request):
print(
request.data
)
ps = PublishSerializers(data=request.data)
# 检验数据有效性
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
# 如果数据有错误则将错误返回
return Response(ps.errors)
class PublishDatailViews(APIView):
# 查看局部数据
def get(self, request, pk):
publish = models.Publish.objects.filter(pk=pk).first()
ps = PublishSerializers(publish, many=False)
return Response(ps.data)
# 修改数据
def put(self, request, pk):
publish = models.Publish.objects.filter(pk=pk).first()
ps = PublishSerializers(data=request.data, instance=publish)
if ps.is_valid():
ps.save()
return Response(ps.data)
else:
return Response(ps.errors)
def delete(self, request, pk):
publish = models.Publish.objects.filter(pk=pk).delete()
return Response("OK")
方式二 使用混合(mixins)
- 首先需要导入五种请求方式
ListModelMixin 获取所有数据 GETCreateModelMixin 添加一条数据 POST----------------------------------------RetrieveModelMixin 查看一条数据 GETUpdateModelMixin 更新一条数据 PUT/PATCHDestroyModelMixin 删除一条数据 delete
- 接着导入专门处理数据的模块
from rest_framework.generics import GenericAPIView
# 导入五种请求方式
from rest_framework.mixins import CreateModelMixin, ListModelMixin, \
DestroyModelMixin, RetrieveModelMixin, UpdateModelMixin
# 导入处理数据
from rest_framework.generics import GenericAPIView
class AuthorView(CreateModelMixin, ListModelMixin, GenericAPIView):
# 必须得以queryset ,serializer_class命名接收这两个参数,覆盖父类
queryset = models.Author.objects.all()
serializer_class = AuthorSerializers
def get(self, request):
# 调用ListModelMixin下的list方法
return self.list(request)
def post(self, request):
return self.create(request)
class AuthorDetailView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView):
queryset = models.Author.objects.all()
serializer_class = AuthorSerializers
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.update(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)
方式三 使用通用的基于类的视图
通过使用mixin类,我们使用更少的代码重写了这些视图,但我们还可以再进一步。REST框架提供了一组已经混合好(mixed-in)的通用视图,我们可以使用它来简化我们的
views.py
模块。
from rest_framework import generics
class BookView(generics.ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = BookSerializers
class BookDetailView(generics.ListCreateAPIView):
queryset = models.Book.objects.all()
serializer_class = BookSerializers
方式四
需要修改url并在url中传入参数修改请求方式调用的方法
- urls.py
url(r"^book/$", views.BookView.as_view({"get":"list", "post": "create"})),
url(r"^book/(?P<pk>\d+)/$", views.BookDetailView.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),
- views.py
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializers
class BookDetailView(ModelViewSet):
queryset = models.Book.objects.all()
serializer_class = BookSerializers
认证组件
在app下新建一个包,在里面创建一个auth.py文件
# 认证组件
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed # 返回报错页面
from CBV_app import models
class TokenAuth(BaseAuthentication):
# 这里必须要使用authenticate定义一个函数,源码内部调用的就是这个名字
def authenticate(self, request):
# 获取用户传来的token参数
token = request.GET.get("token", None)
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
# 返回用户对象跟token_obj
return token_obj.user, token_obj.token
else:
raise AuthenticationFailed("认证失败")
在views.py中创建一个登陆验证类
-
如果在settings.py中设置了全局验证,则需要在登陆中添加: authentication_classes = []
-
如果需要指定某一个需要登陆则在某一个类下添加authentication_classes = [TokenAuth,]
# 获取随机字符串
def get_random(user):
import hashlib, time
time_str = str(time.time())
md5 = hashlib.md5(bytes(user, encoding="utf8"))
md5.update(bytes(time_str, encoding="utf8"))
return md5.hexdigest()
# 定义一个认证类
from rest_framework.views import APIView
from django.http.response import JsonResponse
from CBV_app import models
class LoginView(APIView):
authentication_classes = []
def post(self, request):
res = {"code": 1000, "msg": None}
try:
user = request.data.get("user")
pwd = request.data.get("pwd")
user_obj = models.User.objects.filter(user=user, pwd=pwd).first()
print(user, pwd, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用户名或密码错误"
else:
token = get_random(user)
# 存在着更新,不存在则创建,需要使用defaults传如token否则会报约束失败
models.UserToken.objects.update_or_create(user=user_obj, defaults={"token": token)
res["token"] = token
except Exception as e:
res["code"] = 1002
res["msg"] = str(e)
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
settings.py中配置全局作用
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"CBV_app.utils.auth.TokenAuth"
],
}
局部使用
-
在需要验证的视图类中添加 authentication_classes = [TokenAuth, ]
# 认证组件
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed # 返回报错页面
from CBV_app import models
class TokenAuth(BaseAuthentication):
# 这里必须要使用authenticate定义一个函数,源码内部调用的就是这个名字
def authenticate(self, request):
# 获取用户传来的token参数
token = request.GET.get("token", None)
token_obj = models.UserToken.objects.filter(token=token).first()
if token_obj:
# 返回用户对象跟token_obj
return token_obj.user, token_obj.token
else:
raise AuthenticationFailed("认证失败")
# 获取随机字符串
def get_random(user):
import hashlib, time
time_str = str(time.time())
md5 = hashlib.md5(bytes(user, encoding="utf8"))
md5.update(bytes(time_str, encoding="utf8"))
return md5.hexdigest()
# 定义一个认证类
from rest_framework.views import APIView
from django.http.response import JsonResponse
from CBV_app import models
class LoginView(APIView):
authentication_classes = []
def post(self, request):
res = {"code": 1000, "msg": None}
try:
user = request.data.get("user")
pwd = request.data.get("pwd")
user_obj = models.User.objects.filter(user=user, pwd=pwd).first()
print(user, pwd, user_obj)
if not user_obj:
res["code"] = 1001
res["msg"] = "用户名或密码错误"
else:
token = get_random(user)
# 存在着更新,不存在则创建,需要使用defaults传如token否则会报约束失败
models.UserToken.objects.update_or_create(user=user_obj, defaults={"token": token)
res["token"] = token
except Exception as e:
res["code"] = 1002
res["msg"] = str(e)
return JsonResponse(res, json_dumps_params={"ensure_ascii": False})
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": [
"CBV_app.utils.auth.TokenAuth"
],
}
权限组件
在app下新建一个包,在里面创建一个Permissions.py文件
class SvipPermissions(object):
# 没有权限时返回的提示,必须以message命名
message ="没有权限访问"
# 必须定义has_permissio方法
def has_permission(self, request, view):
print(request.auth.user)
user_type = request.auth.user.type
if user_type == 1:
return True
else:
return False
局部引用权限
-
在views.py中导入
from CBV_app.utils.permissions import SvipPermissions
class SvipPermissions(object):
# 没有权限时返回的提示,必须以message命名
message ="没有权限访问"
# 必须定义has_permissio方法
def has_permission(self, request, view):
print(request.auth.user)
user_type = request.auth.user.type
if user_type == 1:
return True
else:
return False
全局引用权限
- 在settings.py中添加
REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES":[
"app01.utils.permissions.SVIPPermission"]
}
访问频率(throttle)组件
url分发
from django.conf.urls import include
from rest_framework import routers
routes = routers.DefaultRouter()
routes.register("publishes",views.PublishViews)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^',include(routes.urls)) # 直接将url改成这种匹配方式即可
]
响应器
-
JSONRenderer 返回的是json格式的数据页面.
-
BrowsableAPIRenderer
-
默认是两个都添加在里面,可以设置为全局也可设置为局部
全局设置
-
在settings.py中添加下面字典,参数可选
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
}
局部设置
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class PublishViews(ModelViewSet):
renderer_classes = [BrowsableAPIRenderer]
queryset = models.Publish.objects.all()
serializer_class = PublishSerializers
分页器
from django.conf.urls import include
from rest_framework import routers
routes = routers.DefaultRouter()
routes.register("publishes",views.PublishViews)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^',include(routes.urls)) # 直接将url改成这种匹配方式即可
]
响应器
-
JSONRenderer 返回的是json格式的数据页面.
-
BrowsableAPIRenderer
-
默认是两个都添加在里面,可以设置为全局也可设置为局部
全局设置
-
在settings.py中添加下面字典,参数可选
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
}
局部设置
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class PublishViews(ModelViewSet):
renderer_classes = [BrowsableAPIRenderer]
queryset = models.Publish.objects.all()
serializer_class = PublishSerializers
分页器
JSONRenderer 返回的是json格式的数据页面.
BrowsableAPIRenderer
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
}
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class PublishViews(ModelViewSet):
renderer_classes = [BrowsableAPIRenderer]
queryset = models.Publish.objects.all()
serializer_class = PublishSerializers








