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)