zoukankan      html  css  js  c++  java
  • rest framework

    from django.shortcuts import render,HttpResponse
    from rest_framework.views import APIView
    from django.http import JsonResponse
    from appone import models
    from rest_framework.versioning import URLPathVersioning
    from rest_framework.authentication import BaseAuthentication
    from rest_framework.request import Request
    from rest_framework import exceptions
    from rest_framework.throttling import SimpleRateThrottle
    
    
    from rest_framework.authentication import SessionAuthentication
    
    def gen_token(username):
        import time
        import hashlib
        ctime = str(time.time())
        hash = hashlib.md5(username.encode('utf-8'))
        hash.update(ctime.encode('utf-8'))
        return hash.hexdigest()
    #################### 验证相关######################
    class CustomAuthentication(BaseAuthentication):
        def authenticate(self, request):
            """
            Authenticate the request and return a two-tuple of (user, token).
            """
            tk = request.query_params.get('tk')
            if not tk:
                '''
                未登录用户
                '''
                return (None,None)
            '''已登录用户'''
            token_obj = models.Token.objects.filter(token=tk).first()
            if token_obj:
                # (UserInfo对象,Token对象)
                return (token_obj.user,token_obj)
            raise exceptions.AuthenticationFailed("认证失败")
    
        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.
            """
            # return 'Basic realm=api'
            pass
    
    #################### 权限控制######################
    from rest_framework.permissions import AllowAny,BasePermission
    class CustomPermission(BasePermission):
        message = "无权限"
        def has_permission(self, request, view):
            """
            Return `True` if permission is granted, `False` otherwise.
            """
            '''登录用户才能访问'''
            if request.user:
                return True
            return False
    
    #################### 限制访问次数######################
    class CustomAnonRateThrottle(SimpleRateThrottle):
        '''
        未登录用户配置
        '''
        scope = 'Luffy_anon'
    
        def get_cache_key(self, request, view):
            return 'throttle_%(scope)s_%(ident)s'%{
                'scope':self.scope,
                'ident':self.get_ident(request)
            }
    
        def allow_request(self, request, view):
            #已登录用户不管
            if request.user:
                return True
    
            #未登陆
            self.key = self.get_cache_key(request, view)
            self.history = self.cache.get(self.key,[])
    
            self.now = self.timer()
    
    
            while self.history and self.history[-1] <= self.now - self.duration:
                self.history.pop()
            if len(self.history) >= self.num_requests:
                return self.throttle_failure()
            return self.throttle_success()
    class CustomUserRateThrottle(SimpleRateThrottle):
        scope = 'Luffy_user'
    
        def allow_request(self, request, view):
            if not request.user:
                return True
    
            # 获取当前访问用户的唯一标识
            # 用户对所有页面
            # self.key = request.user.user
            # 用户对单页面
            self.key = request.user.user + view.__class__.__name__
            self.history = self.cache.get(self.key,[])
    
            self.now = self.timer()
    
    
            while self.history and self.history[-1] <= self.now - self.duration:
                self.history.pop()
            if len(self.history) >= self.num_requests:
                return self.throttle_failure()
            return self.throttle_success()
    
    
    
    class LoginView(APIView):
        '''
        登录,无限制,用户发送用户名和密码,登录返回token
        '''
        # versioning_class = URLPathVersioning
        def get(self,request,*args,**kwargs):
            return HttpResponse("login get page")
        def post(self,request,*args,**kwargs):
            ret = {'code': 1000, 'msg': None}
            print(request.data)
            user = request.data.get('user')
            pwd = request.data.get('pwd')
    
            user_obj = models.UserInfo.objects.filter(user=user, pwd=pwd).first()
            if user_obj:
                tk = gen_token(user)
                models.Token.objects.update_or_create(user=user_obj, defaults={'token': tk})
                ret['code'] = 1001
                ret['token'] = tk
            else:
                ret['msg'] = "用户名或密码错误"
            return JsonResponse(ret)
    
    class indexView(APIView):
        '''
        首页,所有人都能访问,限制【匿名用户10/m,登录20/m】
        '''
        authentication_classes = [CustomAuthentication, ]
        # permission_classes = [CustomPermission, ]
        throttle_classes = [CustomAnonRateThrottle, CustomUserRateThrottle]
    
        def get(self, request, *args, **kwargs):
            a = self.dispatch
            # print(request.user)
            # print(self.request.user.user)
            return HttpResponse('index get page')
    
        def post(self,request,*args,**kwargs):
            return HttpResponse('index post page')
    
    class OrderView(APIView):
        '''
        订单,登录成功之后,才能查看;限制【登录20/m】
        '''
        authentication_classes = [CustomAuthentication, ]
        permission_classes = [CustomPermission, ]
        throttle_classes = [CustomUserRateThrottle,]
    
        def get(self, request, *args, **kwargs):
            a = self.dispatch
            return HttpResponse('order get page')
        def post(self,request,*args,**kwargs):
            print(request.data)
            return HttpResponse("order post page")
    
    
    
    
    
    ############################路由################
    from rest_framework import serializers
    from rest_framework.response import Response
    from rest_framework.viewsets import GenericViewSet,ModelViewSet
    from rest_framework.viewsets import mixins
    
    class RouteSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    # #手动路由
    # class RouterView(APIView):
    #     def get(self,request,*args,**kwargs):
    #         pk = kwargs.get("pk")
    #         if pk:
    #             obj = models.UserInfo.objects.filter(pk=pk).first()
    #             ser = RouteSerializer(instance=obj,many=False)
    #         else:
    #             user_list = models.UserInfo.objects.all()
    #             ser = RouteSerializer(instance=user_list, many=True)
    #         return Response(ser.data)
    
    
    class RouterView(ModelViewSet):
        queryset = models.UserInfo.objects.all()
        serializer_class = RouteSerializer
    
    
    
    #########################分页######################
    from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
    class PageSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    # class StandardResultsSetPagination(PageNumberPagination):
    #     '''根据页码进行分页'''
    #     # 默认每页显示的数据条数
    #     page_size = 3
    #     # 获取URL参数中设置的每页显示数据条数
    #     page_size_query_param = 'page_size'
    #
    #     # 获取URL参数中传入的页码key
    #     page_query_param = 'page'
    #
    #     # 最大支持的每页显示的数据条数
    #     max_page_size = 5
    
    # class StandardResultsSetPagination(LimitOffsetPagination):
    #     '''位置和个数进行分页'''
    #     # 默认每页显示的数据条数
    #     default_limit = 3
    #     # URL中传入的显示数据条数的参数
    #     limit_query_param = 'limit'
    #     # URL中传入的数据位置的参数
    #     offset_query_param = 'offset'
    #     # 最大每页显得条数
    #     max_limit = None
    class StandardResultsSetPagination(CursorPagination):
        '''游标分页'''
        # URL传入的游标参数
        cursor_query_param = 'cursor'
        # 默认每页显示的数据条数
        page_size = 2
        # URL传入的每页显示条数的参数
        page_size_query_param = 'page_size'
        # 每页显示数据最大条数
        max_page_size = 1000
    
        # 根据ID从大到小排列
        ordering = "id"
    class PagerView(APIView):
    
        def get(self, request, *args, **kwargs):
            user_list = models.UserInfo.objects.all()
    
            # 实例化分页对象,获取数据库中的分页数据
            paginator = StandardResultsSetPagination()
            page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)
    
            # 序列化对象
            serializer = PageSerializer(page_user_list, many=True)
    
            # 生成分页和数据
            response = paginator.get_paginated_response(serializer.data)
            return response
    
    
    ############### 渲染 ##############
    # 用户想要的数据格式:
    # http://127.0.0.1:8002/render/?format=json
    # http://127.0.0.1:8002/render.json
    # 我支持的所有格式: json,admin,form
    
    from rest_framework.renderers import JSONRenderer,AdminRenderer,BrowsableAPIRenderer,HTMLFormRenderer
    class RenderSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    
    from rest_framework.negotiation import DefaultContentNegotiation
    
    class RenderView(APIView):
        # 解析器:content-type
    
        # URL中format传入的参数
        renderer_classes = [JSONRenderer,BrowsableAPIRenderer,AdminRenderer,HTMLFormRenderer]
    
        def get(self,request,*args,**kwargs):
            #form 格式
            # user_list = models.UserInfo.objects.all().first()
            # ser = RenderSerializer(instance=user_list,many=False)
            #admin 格式
            user_list = models.UserInfo.objects.all()
            ser = RenderSerializer(instance=user_list, many=True)
            return Response(ser.data)
    

      

  • 相关阅读:
    webstorm9.0.3 注册码
    SpringMVC 文件上传下载
    Nginx解决post请求405问题
    nginx配置Strict Transport Security
    MySQL修改max_allowed_packet
    ELK批量删除索引
    ELK出现unassigned_shards查看及删除
    Nagios监控mysql主从复制
    Linux DNS原理简介及配置
    root密码重置(Centos 7)
  • 原文地址:https://www.cnblogs.com/hedeyong/p/7922013.html
Copyright © 2011-2022 走看看