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)