rest认证组件,权限组件,频率组件,url注册器,响应器组件,分页器组件
1.认证组件
1.1 认证组件利用token来实现认证
1.2 token认证的大概流程
用户登录===>获取用户名和密码===>查询用户表 如果用户存在,生成token,否则返回错误信息
1.3 示例
补充:自定义的序列化类
BookSerializer.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = ('title', 'price', 'publish', 'authors', 'author_list', 'publish_name', 'publish_city' ) extra_kwargs = { 'publish': {'write_only': True}, 'authors': {'write_only': True} } publish_name = serializers.CharField(max_length=32, read_only=True, source='publish.name') publish_city = serializers.CharField(max_length=32, read_only=True, source='publish.city') author_list = serializers.SerializerMethodField() def get_author_list(self, book_obj): # 拿到queryset开始循环 [{}, {}, {}, {}] authors = list() for author in book_obj.authors.all(): authors.append(author.name) return authors
models.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.db import models #用户表 class User(models.Model) username=models.CharField(max_length=32), password=models.CharFiels(max_length=32), user_type_entry=( (1,VIP), (2,SVIP), (3,VVIP), ), user_type=models.IntegerField(choices=user_type_entry) def __str__(self): return self.username #token表 class UserToken(models.Model): user=models.OneToOneField('User',on_delete=models.CASADE) token=model.CharFields(max_length=128),
urls.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.urls import re_path from serializer import views urlpatterns = [ re_path(r'books/$', views.BookView.as_view({ 'get': 'list', 'post': 'create' })), re_path(r'books/(?P<pk>\d+)/$', views.BookView.as_view({ 'get': 'retrieve', 'put': 'update', 'delete': 'destroy' })), re_path(r'user/$', views.UserView.as_view()), ]
views.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.http import JsonResponse from rest_framework.views import APIView from .models import ( Book, Publish, Author, User, UserToken ) #用户登录认证 class UserView(APIView): def post(self,request): response=dict() fields={"username","password"} user_info=dict() if fields.issubclass(set(request.data.keys())) for key in fields: user_info[key]=request.data[key] user_instance=User.objects.filter(**user_info).first() #如果用户名和密码存在,创建或者更新token if user_info is not None: access_token=str(uuid.uuid4()).replace('-','') UserToken.objects.update_or_create (user=user_instance,defaults={"token":access_token}) response["status_code"]=200 response["status_message"]='登录成功' response["status_token"]=access_token # response["status_role"]=user_instance.get_user_type_diaplay() else: response["status_code"]=201 response["status_message"]="登录失败,用户名或密码错误" #返回状态 return JsonResponse(response) #创建一个认证类 方式一: class UserAuth(): def authenticate_header(self,request): pass def authenticate(self,request): #获取token user_token=request.query_params.get('token') try: token=UserToken.objects.get(token=user_token) return=token.user,token.token except Exception: rais APIException('没有认证') 注意:必须写authenticate_header和authenticate这两个函数名,源码中有声明, authenticate_header中不写内容,但是必须书写,authenticate中书写逻辑 方式二: from rest_framework.authentication import BaseAuthentication class UserAuth(BaseAuthentication): def authenticate(self,request): user_token=request.query_params.get("token") try: token=UserToken.objects.get(token=user_token) return token.user,token.token except Exception: raise APIException("没有认证") #访问book表需要认证和权限 class BookView(ModelViewSet): #认证(只能是authentication_classes) authentication_classes = [UserAuth] #权限(只能是permission_classes) permission_classes = [UserPerm] queryset = Book.objects.all() serializer_class = BookSerializer
2.权限组件
views.py
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
2.1定义一个权限类: class UserPerm(): #自定义返回内容 message="没有权限!" def has_permission(self,request,view): if request.user.user_type ==3: return True return False 2.2 #访问book表需要认证和权限 class BookView(ModelViewSet): #认证(只能是authentication_classes) authentication_classes = [UserAuth] #权限(只能是permission_classes) permission_classes = [UserPerm] queryset = Book.objects.all() serializer_class = BookSerializer
3.频率组件
控制用户访问的频率
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
3.1频率组件的使用 -首先定义一个频率类 -导入模块 from rest_framework.throttling import SimpleRateThrottle -定义类 class RateThrottle(SimpleRateThrottle) rate='5/m'#每分钟访问不能超过5次 def get_cache_key(self,request,view): retuen self.get_ident(request) -指定一个频率类 class BookView(APIView): throttle_class=[RateThrottle] 3.2利用FRF的简单频率来控制用户访问的频率(全局) -导入模块 from rest_framework.throttling import SimpleRateThrottle -定义一个频率类,一定继承SimpleRateThrottle class RateThrottle(SimpleRateThrottle): #指定访问的频率 scope="visit_rate" #指定通过什么方式来区分用户 def get_cache_key(self,request,view): return self.get_ident(request) -在全局seetings中指定频率类和访问的频率 REST_FRAMEWORK={ 'DEFAULT_THROTTLE_CLASSES':("RateThrottle"), "DEFAULE_THROTTLE_RATES"":{ "visit_rate":"5/m", } }
4.url注册器
一键创建url
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
-导入模块 from django.urls import re_path,include import views from rest_framework import routers -生成一个注册器的实例对象 router=routers.DafaultRouter() -将需要生成的url接口注册 router.register(r"books",Views.BookView) -开始自动生成url urlpatterns=[ re_path('^',include(router.urls)), ]
5.响应器组件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
-导入模块 from rest_framework.renderers import JsonRender -指定返回类 class BookView(APIView): render_classes=[JsonRender]
6.分页器组件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
使用方法 -导入模块 from rest_framework.pagination import PageNumberPagination -获取数据 books=Book.objects.all() -创建一个分页器 paginater=PageNumberPagination() -开始分页 paged_books=paginater.paginate_queryset(books,request) -开始序列化 serialized_books=BookSerializer(paged_books,many=True) -返回数据 return Response(serialized_books.data) -分页器的局部实现 -导入模块 from rest_framework.pagination import PageNumberPagination -自定义一个分页类,要继承PageNumberPagination class MyPagination(PageNumberPagination): page_aize=2#每页显示2条数据 page_query_param='p' page_size_query_param='size' max_page_size=5#最多显示5条数据 -实例化一个分页类 paginater=MyPagination() -开始分页 paged_books=paginater.paginate_queryset(books,request) -开始序列化 serialized_books=BookSerializer(paged_books,many=True) -返回数据 return Response(serialized_books.data)