博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
rest_framework 视图/路由/渲染器/认证授权/节流
阅读量:6987 次
发布时间:2019-06-27

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

视图

 1. 整理

class View: django view

class APIView(View):    rest框架基础view,适合直接继承,重写get post方法

class GenericAPIView(views.APIView): 对ApiView进一步包装,方法重写,不适合直接继承使用,适合配合mixin

功能扩展 ,以下各实现部分 get post delete put patch 方法,但未重写asview,需要进一步改写,奇怪的类。。。

 

ViewSetMixin 重写了as_view方法,可以把httpmethod的 get post delete put patch转化为不同方法。

GenericViewSet  可以自定制,适合直接继承,转化httpmethod的 get post delete put patch转化为自定制方法。也可已结合部分XXModelViewSet

ModelViewSet 高度整合, 适合直接继承,用于增删改查可以把httpmethod的 get post delete put patch转化为list,create,destroy,update,pratial_update

 

总结

 

2. modelviewset

views.py

class TestViewSet(ModelViewSet):    queryset = UserInfo.objects.all()    serializer_class = UserInfoSerializer    pagination_class=MyPagination
View Code

urls.py

path('testviewset/',app01views.TestViewSet.as_view({
'get':'list','post':'create'})), re_path('testviewset/(?P
\d+)/',app01views.TestViewSet.as_view({
'get':'retrieve','delete':'destroy','put':'update','patch':'partial_update'})),
View Code

 由于Response返回形式 ,加入?format=json返回json或者在url改写

# http://127.0.0.1:8000/testviewset/json    re_path('testviewset/(?P
\w+)',app01views.TestViewSet.as_view({
'get':'list','post':'create'})),
View Code

 

自动路由

 当实现了modelviewset时的的自动路由

from rest_framework import routersrouter=routers.DefaultRouter()router.register(r'testrouter',app01views.TestViewSet)urlpatterns = [    path('',include(router.urls)),]#访问http://127.0.0.1:8000/testrouter/
View Code

from rest_framework import routersrouter=routers.DefaultRouter()router.register(r'',app01views.TestViewSet)urlpatterns = [    path('testrouter/',include(router.urls)),]
View Code

 

渲染器

from rest_framework.renderers import AdminRenderer,JSONRenderer,BrowsableAPIRendererclass TestViewSet(ModelViewSet):    renderer_classes = [JSONRenderer,BrowsableAPIRenderer]    queryset = UserInfo.objects.all()    serializer_class = UserInfoSerializer    pagination_class=MyPagination
View Code

 

认证授权

参考http://www.cnblogs.com/wupeiqi/articles/7805382.html

from rest_framework.authentication import BaseAuthenticationfrom rest_framework.permissions import BasePermissionclass TestAuthentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        val = request.query_params.get('token')        if val not in token_list:            raise exceptions.AuthenticationFailed("用户认证失败")        return ('登录用户', '用户token')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        passclass TestPermission(BasePermission):    message = "权限验证失败"    def has_permission(self, request, view):        """        判断是否有权限访问当前请求        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :return: True有权限;False无权限        """        if request.user == "管理员":            return True    # GenericAPIView中get_object时调用    def has_object_permission(self, request, view, obj):        """        视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :param obj:         :return: True有权限;False无权限        """        if request.user == "管理员":            return Trueclass TestView(APIView):    # 认证的动作是由request.user触发    authentication_classes = [TestAuthentication, ]    # 权限    # 循环执行所有的权限    permission_classes = [TestPermission, ]    def get(self, request, *args, **kwargs):
View Code

全局

REST_FRAMEWORK = {    'UNAUTHENTICATED_USER': None,    'UNAUTHENTICATED_TOKEN': None,    "DEFAULT_AUTHENTICATION_CLASSES": [        "web.utils.TestAuthentication",    ],    "DEFAULT_PERMISSION_CLASSES": [        "web.utils.TestPermission",    ],}
View Code

 节流

 

import timefrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import exceptionsfrom rest_framework.throttling import BaseThrottlefrom rest_framework.settings import api_settings# 保存访问记录RECORD = {    '用户IP': [12312139, 12312135, 12312133, ]}class TestThrottle(BaseThrottle):    ctime = time.time    def get_ident(self, request):        """        根据用户IP和代理IP,当做请求者的唯一IP        Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR        if present and number of proxies is > 0. If not use all of        HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.        """        xff = request.META.get('HTTP_X_FORWARDED_FOR')        remote_addr = request.META.get('REMOTE_ADDR')        num_proxies = api_settings.NUM_PROXIES        if num_proxies is not None:            if num_proxies == 0 or xff is None:                return remote_addr            addrs = xff.split(',')            client_addr = addrs[-min(num_proxies, len(addrs))]            return client_addr.strip()        return ''.join(xff.split()) if xff else remote_addr    def allow_request(self, request, view):        """        是否仍然在允许范围内        Return `True` if the request should be allowed, `False` otherwise.        :param request:         :param view:         :return: True,表示可以通过;False表示已超过限制,不允许访问        """        # 获取用户唯一标识(如:IP)        # 允许一分钟访问10次        num_request = 10        time_request = 60        now = self.ctime()        ident = self.get_ident(request)        self.ident = ident        if ident not in RECORD:            RECORD[ident] = [now, ]            return True        history = RECORD[ident]        while history and history[-1] <= now - time_request:            history.pop()        if len(history) < num_request:            history.insert(0, now)            return True    def wait(self):        """        多少秒后可以允许继续访问        Optionally, return a recommended number of seconds to wait before        the next request.        """        last_time = RECORD[self.ident][0]        now = self.ctime()        return int(60 + last_time - now)class TestView(APIView):    throttle_classes = [TestThrottle, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')    def throttled(self, request, wait):        """        访问次数被限制时,定制错误信息        """        class Throttled(exceptions.Throttled):            default_detail = '请求被限制.'            extra_detail_singular = '请 {wait} 秒之后再重试.'            extra_detail_plural = '请 {wait} 秒之后再重试.'        raise Throttled(wait)
View Code

 

转载于:https://www.cnblogs.com/infaaf/p/9580685.html

你可能感兴趣的文章
svg矢量图制作工具(Sketsa SVG Editor) v7.1.1 中文免费版
查看>>
关于ListBox在Grid中无法充满的问题
查看>>
WPF之托盘图标的设定
查看>>
HTTP协议详解(真的很经典)
查看>>
(转)什么是云计算
查看>>
新书推荐:细说PHP(含样章试读)
查看>>
shell常识总结
查看>>
大道至简,职场上做人做事做管理
查看>>
make 参数定义
查看>>
java从字符串中提取数字
查看>>
Android深入浅出系列之服务机制—1.Android中的Service
查看>>
MVC、MVP以及Model2[上篇]
查看>>
数据库隐式类型转换
查看>>
分享5个主流的HTML5开发工具
查看>>
基于Ionic2的开源项目
查看>>
分析Linux内核创建一个新进程的过程【转】
查看>>
周锦民:腾讯在线教育视频互动直播间技术实践
查看>>
[转]UML类图、关系及其JAVA代码
查看>>
PhotoShop算法原理解析系列 - 像素化---》碎片。
查看>>
设计模式之责任链模式
查看>>