目录
Django框架之drf
一、认证组件
简介:
登录认证的限制
认证组件是drf框架给我们提供的认证接口,它能够在请求进入视图函数/类前进验证(例如:认证用户是否登录),对不符合认证的请求进行拦截并返回校验失败的信息
1、认证组件使用步骤
模块地址:
from rest_framework.authentication import BaseAuthentication
用法简介:
# 1、创建一个专门用于认证的py文件,写一个类继承BaseAuthentication # 2、重写authenticate方法,在方法内验证token # 3、如果认证成功,返回两个值【返回None或两个值(当前登录的对象和token)】 # 4、认证不通过,抛异常AuthenticationFailed(异常信息) # 5、局部使用和全局使用 -局部使用:# 在需要使用认证的视图类下管理接口 class BookDetailView(ViewSetMixin, RetrieveAPIView): authentication_classes = [LoginAuth] # 列表,可以添加多个 -全局使用:# 在django的setting.py文件种添加配置 REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth'] } -局部禁用:# 全局开启,局部禁用 class BookDetailView(ViewSetMixin, RetrieveAPIView): authentication_classes = []
2、代码用法
认证类代码:(authentica.py)
class LoginAuth(BaseAuthentication): # 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常 def authenticate(self, request): # 请求中是否携带token,判断是否登录,放在地址栏中 token = request.query_params.get('token', None) # 判断前端是否传入token if token: # 去表中查找token user_token = UserToken.objects.filter(token=token).first() # 判断是否查到token if user_token: # 找到了返回两个值:登录的对象和token return user_token.user, token else: # 没有登录抛异常 raise AuthenticationFailed('token认证失败') else: raise AuthenticationFailed('token没传')
视图类代码
# 查询所有 class BookView(ViewSetMixin, ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 控制认证的接口(列表,可以在认证的py文件下编写多个认证) authentication_classes = [LoginAuth] # 局部认证
路由代码
from django.urls import path, include from app01 import views # 第一步:导入模块 from rest_framework.routers import SimpleRouter # 第二步:实例化对象 router = SimpleRouter() # 第三步:注册路由 router.register('books', views.BookView, 'books') urlpatterns = [ path('', include(router.urls)) ]


二、权限组件
简介:
在我们使用的一些app或者网页中(爱奇艺,腾讯视频),都会有一些会员接口(需要购买会员才能够使用或者观看),权限组件就是对用户的这一权限进行验证,在请求进入视图类/函数代码前进行校验,校验失败后直接将请求拦截,并返回校验失败的信息
1、权限组件的使用步骤
模块地址:
from rest_framework.permissions import BasePermission
用法简介:
# 1、创建一个专门用于编写权限组件的py文件,写一个权限类,继承BasePermission # 2、重写has_permission方法(在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户) # 3、如果有权限,返回True # 4、没有权限,返回False(定制返回的中文: self.message='中文') # 5、局部使用和全局使用 -局部使用: # 在某个视图类中设置接口(不会影响别的视图类) class BookDetailView(ViewSetMixin, RetrieveAPIView): permission_classes = [CommonPermission] -全局使用: # django的settings.py中配置,影响全局 REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'app01.permissions.CommonPermission', ], } -局部禁用:# 全局配置局部禁用 class BookDetailView(ViewSetMixin, RetrieveAPIView): permission_classes = []
2、代码用法
权限类代码(perssion.py)
# 写权限类,写一个类,继承基类BasePermission,重写has_permission方法,在方法中实现权限认证,如果有权限return True ,如果没有权限,返回False from rest_framework.permissions import BasePermission class CommonPermission(BasePermission): def has_permission(self, request, view): # 实现权限的控制 ---》知道当前登录用户是谁?当前登录用户是 request.user if request.user.user_type == 1: return True else: # 没有权限,向对象中放一个属性 message # 如果表模型中,使用了choice,就可以通过 get_字段名_display() 拿到choice对应的中文 self.message = '您是【%s】,您没有权限' % request.user.get_user_type_display() return False
视图类代码:
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 局部认证 authentication_classes = [LoginAuth] # 权限认证(将编写的频率类导入过来) permission_classes = [CommentPermission]

三、频率
简介:
频率是指,控制某个接口访问频率(次数)
1、频率组件的使用步骤
模块地址:
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle # BaseThrottle:需要手动编写的代码较多 # SimpleRateThrottle: 需要手动编写的代码较少(用这个)
用法简介
# 1、创建一个专门用来编写频率组件的py文件,写一个频率类,继承SimpleRateThrottle # 2、重写get_cache_key方法,返回什么,就以什么做限制----》ip(用户id做限制) # 3、配置一个类属性scope = 'book_5_m' # 4、在django的配置文件中编写频率次数 REST_FRAMEWORK = { 'DEFAULT_THROTTLE_RATES': { 'book_5_m': '5/m', # 一分钟五次 }, } # 5、局部使用和全局使用 -局部使用: # 只影响当前的视图类 class BookView(ModelViewSet): throttle_classes = [CommentThrottle] -全局配置:影响全局 REST_FRAMEWORK = { 'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'], } -局部禁用: class BookView(ModelViewSet): throttle_classes = [CommentThrottle]
2、代码用法
频率类代码(throttle.py)
from rest_framework.throttling import BaseThrottle, SimpleRateThrottle class CommentThrottle(SimpleRateThrottle): # 创建一个用于控制频率的变量名(需要传入配置文件) scope = 'book_5_m' def get_cache_key(self, request, view): # 返回什么就以什么做限制(request.META.get('REMOTE_ADDR')以IP做限制) return request.META.get('REMOTE_ADDR')
视图类代码
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 频率组件 throttle_classes = [CommentThrottle]
django配置文件
REST_FRAMEWORK = { # 控制访问频率 'DEFAULT_THROTTLE_RATES': { 'book_5_m': '5/m', # 一分钟五次 }, }

四、过滤的多种用法
简介:
过滤是指在使用查询的时候,我们可以通过条件来过滤掉不需要的内容(例如:使用淘宝购物时,购买某种物品,过滤掉价格低于100元的商品)
# restful规范中,要求了,请求地址中带过滤条件 -5个接口中,只有一个接口需要有过滤和排序,查询所有接口
1、继承APIView自己写
class BookView(APIView): def get(self,request): # 获取get请求携带的参数 name=request.query_params.get('name') # 通过filter进行过滤 books = Book.objects.filter(name=name)
2、使用drf的内置过滤(继承GenericAPIview)
模块地址:
-该方法为模糊查询
from rest_framework.filters import SearchFilter
代码用法:
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 实例化过滤对象 filter_backends = [SearchFilter] # 指定过滤的字段(模糊查询) search_fields = ['name', 'price']
搜索方式:
# name或price中只要有关键字就会搜出来 (只能用search=xxx的方式) http://127.0.0.1:8000/api/v1/books/?search=西游记

3、使用第三方插件过滤(精准过滤)
第三方插件:
# 插件名称: django-filter # 安装插件: pip3.8 install django-filter
模块地址:
from django_filters.rest_framework import DjangoFilterBackend
代码用法:
from rest_framework.viewsets import ModelViewSet from .models import Book from .serializer import BookSerializer from django_filters.rest_framework import DjangoFilterBackend class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 第三方过滤插件 filter_backends = [DjangoFilterBackend] # 查询的字段 filterset_fields = ['pk','name', 'price']
搜索方式:
http://127.0.0.1:8000/api/books/?price=99 http://127.0.0.1:8000/api/books/?price=99&name=呐喊

4、使用过滤组件
4、1.定制过滤组件的使用方式与步骤
模块地址:
from rest_framework.filters import BaseFilterBackend
用法简介:
# 1、创建一个专门用于过滤的py文件,写一个类继承BaseFilterBackend # 2、重写filter_queryset方法,在方法内部进行过滤 # 3、直接返回过滤后的对象 # 4、如果没有过滤直接返回所有数据 # 5、局部使用 -局部使用: class BookView(ViewSetMixin, ListAPIView): queryset = Book.objects.all() serializer_class = BookSerializer # 在类表内填写过滤的类 filter_backends = [CommonFilter] # 可以定制多个,从左往右,依次执行
4、2.代码用法
过滤类代码(filters.py)
from rest_framework.filters import BaseFilterBackend class CommonFilter(BaseFilterBackend): # 重写的类,编写过滤吧的内容 def filter_queryset(self, request, queryset, view): # 获取过滤的条件 filter_comment = request.query_params.get('price_gt', None) # 判断前端是否传入过滤条件 if filter_comment: # 根据条件进行赛选内容 books_queryset_filter = queryset.filter(price__gt=100) # 返回过滤后的数据 return books_queryset_filter return queryset
视图类代码
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 第三方过滤插件 filter_backends = [CommonFilter]
五、排序
1、用法简介
用法简介:
排序需要和自定义过滤继承同一个父类,需要将排序的对象填入在过滤的列表内,并且放在其他参数的前方
模块地址:
from rest_framework.filters import OrderingFilter
2、代码用法
视图类代码
from rest_framework.viewsets import ModelViewSet from .models import Book from .serializer import BookSerializer from django_filters.rest_framework import DjangoFilterBackend from .filters import CommonFilter from rest_framework.filters import OrderingFilter class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 第三方过滤插件(OrderingFilter放在其他过滤参数前) filter_backends = [OrderingFilter, DjangoFilterBackend, CommonFilter] # 查询的字段 filterset_fields = ['id', 'name', 'price'] # 指定排序的字段(-是降序,默认升序) ordering_fields = ['price']
搜索用法
# 默认升序 http://127.0.0.1:8000/api/books/?price_gt=60&ordering=price # 降序 http://127.0.0.1:8000/api/books/?price_gt=60&ordering=-price
六、分页
1、用法简介
- 只有查询所有接口才能到用到分页
- drf内置了三个分页器,分别应对三种分页方式
- 内置的分页类不能直接使用,需要继承,定制一些参数后才能使用
2、三种分页器的用法
模块地址:
三种分页器在同一个父类中
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination
视图类代码:
class BookView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookSerializer # 指定分页器 pagination_class = ‘指定使用的分分页器’(需要导入分页器类)
2、1.自定义分页器
from rest_framework.pagination import PageNumberPagination, CursorPagination, LimitOffsetPagination # 第一种:通常用于web端(常规分页器) class CommonPageNumberPagination(PageNumberPagination): # 每页显示2条 page_size = 2 # page=10 查询第10页的数据,每页显示2条 page_query_param = 'page' # page=10&size=5 查询第10页,每页显示5条 page_size_query_param = 'size' # 每页最大显示10条 max_page_size = 5 # 第二种:可以控制每页显示的数量(偏移分页,用的较少) class CommonLimitOffsetPagination(CursorPagination): # 每页显示2条 default_limit = 3 # limit=3 取3条 limit_query_param = 'limit' # offset=1 从第一个位置开始,取limit条 offset_query_param = 'offset' # 最大显示数 max_limit = 5 # 第三种:游标分页器(app常用,拉到哪里显示多少数据) class CommonCursorPagination(CursorPagination): # 查询参数(可以随便写,需要在前端路由对上) cursor_query_param = 'p' # 每页多少条 page_size = 2 # 排序的字段 ordering = 'id'
前端对应搜索方式:
#基本分页方式(基本是这种,网页端): http://127.0.0.1:8000/api/v1/books/?page=2&size=3 # 偏移分页 :从第一条开始,取4条 http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1 # 游标分页: http://127.0.0.1:8000/api/books/?p=cD0x