博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django REST_framework框架 03
阅读量:6121 次
发布时间:2019-06-21

本文共 6355 字,大约阅读时间需要 21 分钟。

权限组件

源码

权限组件的源码执行过程和之前的认证组件是相同的,如下:

self.check_permissions(request)
def check_permissions(self, request):    """    Check if the request should be permitted.    Raises an appropriate exception if the request is not permitted.    """    for permission in self.get_permissions():        if not permission.has_permission(request, self):            self.permission_denied(                request, message=getattr(permission, 'message', None)            )

思考:如果要做权限认证,我们首先要知道当前登录的用户是谁,那么我们如何知道呢?

首先rest_framework中的三个组件是按顺序执行的:

#认证组件self.perform_authentication(request)#权限组件self.check_permissions(request)#频率组件self.check_throttles(request)

在第一个执行的认证组件源码中有这样一段代码

self.user, self.auth = user_auth_tuple

这个user_auth_tuple恰巧就是我们自定义认证视图时返回的那个元祖

class TokenAuth(BaseAuthentication):def authenticate(self, request):......return token_obj.user, token_obj.token #需要返回一个元组

因此此时的self.user=token_obj.user,self.auth=token_obj.token

局部视图权限

在app01.service.permissions.py中:

from rest_framework.permissions import BasePermissionclass SVIPPermission(BasePermission):    message = "SVIP才能访问" #没通过验证则返回错误    def has_permission(self, request, view): #固定写法        if request.user.user_type == 3:            return True        return False

在views.py:

class AuthorView(viewsets.ModelViewSet):    authentication_classes = [TokenAuth,]    permission_classes = [SVIPPermission,]    queryset = Author.objects.all()    serializer_class = AuthorModelSerializers

全局视图权限

REST_FRAMEWORK={    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],    "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",]}

throttle(访问频率)组件

源码

self.check_throttles(request)
def check_throttles(self, request):    """    Check if request should be throttled.    Raises an appropriate exception if the request is throttled.    """    for throttle in self.get_throttles():        if not throttle.allow_request(request, self):            self.throttled(request, throttle.wait())

局部视图throttle

在app01.service.throttles.py中:

from rest_framework.throttling import BaseThrottleclass VisitThrottle(BaseThrottle):    def allow_request(self,request,view):        if 1:            return True        return False

在views.py中:

from app01.service.throttles import *class BookViewSet(generics.ListCreateAPIView):    throttle_classes = [VisitThrottle,]    queryset = Book.objects.all()    serializer_class = BookSerializers

全局视图throttle

REST_FRAMEWORK={    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],    "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],    "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",]}

内置throttle类

解析器

解析器是将接收到的数据转换为我们所需要的数据类型,是反序列化的过程,例如将前端传过来的JSON解析为字典,rest_framework可以直接从request.data中取出反序列化后的JSON数据,依赖的就是解析器

局部视图

from rest_framework.parsers import JSONParser,FormParserclass PublishViewSet(generics.ListCreateAPIView):    parser_classes = [FormParser,JSONParser] #只写了两种解析器,默认有三种    queryset = Publish.objects.all()    serializer_class = PublshSerializers    def post(self, request, *args, **kwargs):        print("request.data",request.data)        return self.create(request, *args, **kwargs)

全局视图

REST_FRAMEWORK={    "DEFAULT_AUTHENTICATION_CLASSES":["app01.service.auth.Authentication",],    "DEFAULT_PERMISSION_CLASSES":["app01.service.permissions.SVIPPermission",],    "DEFAULT_THROTTLE_CLASSES":["app01.service.throttles.VisitThrottle",],    "DEFAULT_THROTTLE_RATES":{        "visit_rate":"5/m",    },    "DEFAULT_PARSER_CLASSES":['rest_framework.parsers.FormParser',]}

如果我们自己不设置parser_classes那么就会去父类中找

parser_classes = api_settings.DEFAULT_PARSER_CLASSES

而父类中的默认设置已经包含了常用的三种解析,包括解析JSON数据和urlencoded数据等,因此这里不太需要修改

'DEFAULT_PARSER_CLASSES': ('rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser','rest_framework.parsers.MultiPartParser'),

思考:在实际开发过程中,如果我们需要解析一个特殊的数据类型,那么可以自己写一个解析器(类),然后加到parser_classes = []中,这样就可以在request.data中直接取出这种特殊数据类型反序列化后的结果了

URLs-路由控制补充知识

进一步封装url

原有url

我们知道下面两条url都针对一个视图类,但每个表这写两条url的话就会造成代码重复,因为不同表的每条url只有视图类的名字和反向解析的名字有区别而已,这里可以进一步封装

url(r'^authors/$', views.AuthorView.as_view({"get": "list", "post": "create"}), name="author"),url(r'^authors/(?P
\d+)/$', views.AuthorModelView.as_view({"get":"retrieve","put":"update","delete":"destroy"}),name="detailauthor"),
class AuthorView(viewsets.ModelViewSet):    queryset = Author.objects.all()    serializer_class = AuthorModelSerializers

新url

from rest_framework import routersfrom django.conf.urls import includefrom app01 import viewsrouter = routers.DefaultRouter()  #实例化一个对象router.register(r'authors', views.AuthorView)  #注册,前面写表名,后面写视图类的名字urlpatterns = [    url(r'^admin/', admin.site.urls),    url('', include(router.urls)),]

再访问就会自动生成四条url

^authors/$ [name='author-list']^authors\.(?P
[a-z0-9]+)/?$ [name='author-list']^authors/(?P
[^/.]+)/$ [name='author-detail']^authors/(?P
[^/.]+)\.(?P
[a-z0-9]+)/?$ [name='author-detail']

分页组件

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination

分页器A-简单分页

class PNPagination(PageNumberPagination):    page_size = 2 #默认每页显示几条    page_query_param = 'page' #url上get请求时的关键字,表示第几页 ?page=2    page_size_query_param = 'size' #url关键字,临时设置每页显示几条,与默认区分 ?size=2    max_page_size = 3 #用于限制page_size_query_param的最大值,即每页显示条数最多不能超过这个限制

分页器B-偏移分页

class MyLimitOffsetPagination(LimitOffsetPagination):    default_limit = 3 #默认显示几条数据    limit_query_param = 'limit' #url关键字,临时设置每页显示几条数据    offset_query_param = 'offset' #url关键字,偏移,默认从0开始,与limit可以配合

viewsA:

class BookView(APIView):    def get(self, request):        book_list = Book.objects.all()        # 分页        pnp = MyLimitOffsetPagination()        pager_books = pnp.paginate_queryset(book_list, request, self)        ret = BookModelSerializers(pager_books, many=True, context={'request': request})        # 此处的Response来自rest_framework        return Response(ret.data)

viewsB:

class AuthorView(viewsets.ModelViewSet):    queryset = Author.objects.all()    serializer_class = AuthorModelSerializers    pagination_class = MyLimitOffsetPagination #定义分页器类
返回值{    "count": 4, #数据总数    "next": "http://127.0.0.1:8000/authors/?page=2", #下一页的url    "previous": null,......}

偏移分页示例

每页显示一条数据的同时,从第一条数据开始向右偏移两条数据,显示结果是第三条数据

每页显示两条数据的同时,从第一条数据开始向右偏移两条数据,显示结果是第三第四条数据

转载于:https://blog.51cto.com/dzm911/2345109

你可能感兴趣的文章
9、Dubbo-配置(4)
查看>>
前端第七天
查看>>
BZOJ 2190[SDOI2008]仪仗队
查看>>
图解SSH原理及两种登录方法
查看>>
[转载] 七龙珠第一部——第058话 魔境圣地
查看>>
【总结整理】JQuery基础学习---样式篇
查看>>
查询个人站点的文章、分类和标签查询
查看>>
基础知识:数字、字符串、列表 的类型及内置方法
查看>>
JSP的隐式对象
查看>>
P127、面试题20:顺时针打印矩阵
查看>>
JS图片跟着鼠标跑效果
查看>>
[SCOI2005][BZOJ 1084]最大子矩阵
查看>>
学习笔记之Data Visualization
查看>>
Leetcode 3. Longest Substring Without Repeating Characters
查看>>
【FJOI2015】金币换位问题
查看>>
数学之美系列二十 -- 自然语言处理的教父 马库斯
查看>>
Android实现自定义位置无标题Dialog
查看>>
面试总结
查看>>
Chrome浏览器播放HTML5音频没声音的解决方案
查看>>
easyui datagrid 行编辑功能
查看>>