Django中rest_framework的认证组件,权限组件,频率组件,序列化组件的最简化版接口
url
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^login/', views.Login.as_view()), # Book表 url(r'^books/$',views.BookHandle.as_view({ 'get':'list', 'post':'create' })), url(r'^books/(?P<pk>\d+)/',views.BookHandle.as_view({ 'get':'retrieve', 'put':'update', 'delete':'destroy' })), # 'get': 'retrieve', # 'put': 'update', # 'delete': 'destroy' # Author表 url(r'^authors/$',views.AuthorHandle.as_view({ 'get':'list', 'post':'create' })), url(r'^authors/(?P<pk>\d+)/',views.AuthorHandle.as_view({ 'get':'retrieve', 'put':'update', 'delete':'destroy' })), # Publish表 url(r'^publishs/$',views.PublishHandle.as_view({ 'get':'list', 'post':'create' })), url(r'^publishs/(?P<pk>\d+)/',views.PublishHandle.as_view({ 'get':'retrieve', 'put':'update', 'delete':'destroy' })), ]
view
from app01.all_serializers import BookSerializer,AuthorSerializer,PublishSerializer from app01 import models from rest_framework.viewsets import ModelViewSet from rest_framework.response import Response from rest_framework.views import APIView import uuid # Create your views here. # 登陆设置token,为认证做铺垫 class Login(APIView): # 200:成功 400:失败 dic = {'code':None,'username':None,'msg':None,'token':None} def post(self,request): uname = request.data.get('username') upwd = request.data.get('password') user_obj = models.User.objects.filter(username=uname,password=upwd).first() if user_obj: random_str = uuid.uuid4() models.My_token.objects.update_or_create( defaults={'token':random_str}, user = user_obj ) self.dic['code'] = 200 self.dic['username'] = uname self.dic['msg'] = '登陆成功' self.dic['token'] = random_str else: self.dic['code'] = 400 self.dic['msg'] = '登陆失败' return Response(self.dic) # 认证组件的类 from rest_framework.exceptions import AuthenticationFailed #认证失败,抛出异常 from rest_framework.authentication import BaseAuthentication class UserInfo(BaseAuthentication): # 这个方法可以pass,但是必须存在 def authenticate_header(self,request): pass # authenticate方法固定的,并且必须有个参数,这个参数是新的request对象,不信,看源码 def authenticate(self,request): # query_params相当于GET.get,获取get请求时,?后面携带的参数 token = request.query_params.get('token') my_token_obj = models.My_token.objects.filter(token=token).first() if my_token_obj: # 返回的第一个参数request.user是User表的对象,第二个参数request.auth是token return my_token_obj.user,token else: raise AuthenticationFailed('认证失败') #权限组件的类 from rest_framework.permissions import BasePermission class UserPermission(BasePermission): message = 'VIP以上权限才能访问' # 这个方法必须存在 def has_permission(self,request,view): # 认证组件的时候,返回两个值,一个是request.user,一个是request.auth. if request.user.usertype >= 2 : return True return False # return True #访问频率组件的类 from rest_framework.throttling import BaseThrottle import time #定义一个全局字典,保证用户访问过后,这个字典里面的值还存在 throttle_dic = {} class MyThrottle(BaseThrottle): mytime = 10 mycount = 5 # 当前请求的时间 # 定义方法 方法名和参数不能变 def allow_request(self, request, view): # 获取登录主机的id id = request.META.get('REMOTE_ADDR') # 定义一个类变量,因为wait方法会用到 self.now_time = time.time() # 当这个主机ID 没有请求过,请继续执行 if id not in throttle_dic: throttle_dic[id] = [] # 定义一个类变量,用来定义这个字典里面的列表,在wait方法中会用到 self.lis = throttle_dic[id] # 当这个主机ID有值,且当前时间-列表最后存的时间,大于时间间隔10s时,删除掉最后存的时间,依次循环 while self.lis and self.now_time - self.lis[-1] >= self.mytime : self.lis.pop() # 当主机ID里面存的数据的数量小于定义的频率次数(5次),把当前时间存入这个列表,且证明可以访问 if len(self.lis) < self.mycount : self.lis.insert(0,self.now_time) return True # 否则,说明在规定的时间内,访问的次数超过上限 else: return False # 这个方法必须存在 def wait(self): return self.lis[-1] + self.mytime - self.now_time
#书籍表的视图函数
class BookHandle(ModelViewSet):
#添加认证组件,参数不能变
authentication_classes = [UserInfo,]
#添加权限组件,参数不能变
permission_classes = [UserPermission,]
#添加频率组件,参数不能变
throttle_classes = [MyThrottle,]
queryset = models.Book.objects.all()
# 序列化组件,必须要有
serializer_class = BookSerializer
#作者表的视图函数
class AuthorHandle(ModelViewSet):
# 添加认证组件,参数不能变
authentication_classes = [UserInfo, ]
# 添加权限组件,参数不能变
permission_classes = [UserPermission, ]
# 添加频率组件,参数不能变
throttle_classes = [MyThrottle, ]
queryset = models.Author.objects.all()
# 序列化组件,必须要有
serializer_class = AuthorSerializer
#出版社表的序列化组件
class PublishHandle(ModelViewSet):
# 添加认证组件,参数不能变
authentication_classes = [UserInfo, ]
# 添加权限组件,参数不能变
permission_classes = [UserPermission, ]
# 添加频率组件,参数不能变
throttle_classes = [MyThrottle, ]
queryset = models.Publish.objects.all()
# 序列化组件,必须要有
serializer_class = PublishSerializer
all_serializers
from rest_framework import serializers from app01 import models # Book表的序列化组件 class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = '__all__' #多对一字段(不要跟字段名重名) 参数source,read_only这两个参数要有 publish_name = serializers.CharField(max_length=32,source='publish.name',read_only=True) #多对多字段(不要跟字段名重名) author_name = serializers.SerializerMethodField() def get_author_name(self,obj): lis = [] author_obj_list = obj.authors.all() for author_obj in author_obj_list: dic = {} dic['name'] = author_obj.name lis.append(dic) return lis # Author表的序列化组件 class AuthorSerializer(serializers.ModelSerializer): class Meta: model = models.Author fields = '__all__' # Publish表的序列化组件 class PublishSerializer(serializers.ModelSerializer): class Meta: model = models.Publish fields = '__all__'
models
from django.db import models # Create your models here. class Author(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) age=models.IntegerField() class AuthorDetail(models.Model): nid = models.AutoField(primary_key=True) birthday=models.DateField() telephone=models.BigIntegerField() addr=models.CharField( max_length=64) class Publish(models.Model): nid = models.AutoField(primary_key=True) name=models.CharField( max_length=32) city=models.CharField( max_length=32) email=models.EmailField() def __str__(self): return self.name class Book(models.Model): nid = models.AutoField(primary_key=True) title = models.CharField( max_length=32) # publishDate=models.DateField() price=models.DecimalField(max_digits=5,decimal_places=2) publish=models.ForeignKey(to="Publish",to_field="nid",on_delete=models.CASCADE) #多对一到Publish表 authors=models.ManyToManyField(to='Author',) #多对多到Author表 class User(models.Model): username = models.CharField(max_length=32) password = models.CharField(max_length=32) my_type = ((1,'IP'),(2,'VIP'),(3,'SVIP')) usertype = models.IntegerField(choices=my_type,default=1) class My_token(models.Model): token = models.CharField(max_length=32) user = models.OneToOneField('User')