1 认证组件
# 以后 有的接口需要登录后才能访问 有的接口 不登录就能访问
-登录认证的限制
# 写一个登录接口, 返回token, 以后只要带着token过来 就是登录了,不带,就没有登录
# 查询所有不需要登录就能访问
# 查询单个, 需要登录才能访问
1.1 认证组件使用步骤
# 1 写一个认证类, 继承BaseAuthentication
from rest_framework.authentication import BaseAuthentication
# 2 重写authenticate方法 在该方法在中实现登录认证: token在哪里带的
# 3 如果认证成功 就返回两个值 【返回None或者两个值】
# 4 认证不通过,抛异常AuthenticationFailed
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
# 实现认证 如果登录 继续执行代码 不是则抛异常
# 请求体中是否携带token 判断是否登录
token = request.query_params.get('token', None)
if token: # 前端传入token 去表中查 如果可以查到 返回两个值[固定的:当前登录用户,token]
user_token = UserToken.objects.filter(token=token).first()
if user_token:
return user_token.user, token
else:
# 没有登陆抛异常
raise AuthenticationFailed('token认证失败')
else:
raise AuthenticationFailed('token没传')
# 5 局部使用和全局使用
-局部: 只在某个视图类中使用 【当前视图类管理的所有接口】
class BookDetailView(ViewSetMixin, RetrieveAPIView):
authentication_classes = [loginAuth]
-全局: 全局所有接口都生效(登录接口不要)
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
}
-局部禁用:
class BookDetailView(ViewSetMixin, RetrieveAPIView):
#queryset = Book.objects.all()
#serializer_class = BookSerializer
authentication_classes = []
1.1代码
### 视图
# 查询所有
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# 查询单个
class BookDetailView(ViewSetMixin, RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
# authentication_classes = [LoginAuth] # 需要写一个认证类
### 认证类代码
from rest_framework.authentication import BaseAuthentication
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
# 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常
# 请求中是否携带token,判断是否登录,放在地址栏中
token = request.query_params.get('token', None)
if token: # 前端传入token了,去表中查,如果能查到,登录了,返回两个值[固定的:当前登录用户,token]
user_token = UserToken.objects.filter(token=token).first()
if user_token:
return user_token.user, token
else:
# 没有登录抛异常
raise AuthenticationFailed('token认证失败')
else:
raise AuthenticationFailed('token没传')
### 路由代码
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', views.BookView, 'books')
router.register('books', views.BookDetailView, 'books')
2 权限组件
# 即使登录成功 有些接口 还是不能访问 权限问题
# 有的有权限 有的没权限 vip
# 查询单个和查询所有,都要登录才能访问----》全局认证
-查询单个需要超级管理员才能访问
-查询所有,所有登录用户都能访问
# 权限是一个字段,在User表中,加入user_type字段
2.1 权限的使用
# 1 写一个权限类 继承BasePermission
# 2 重写has_permission, 在该方法中实现权限认证, 在这方法中,request.user就是当前登录用户
# 3 如果有权限 返回True
# 4 没有权限 返回False 定制返回的中文: self.message='中文'
# 5 局部使用和全局使用
-局部: 只在某个视图类中使用【当前视图类管理的所有接口】
class BookDetailView(ViewSetMixin, RetrieveAPIView):
permission_classes = [CommonPermission]
-全局: 全局所有接口都生效
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.permissions.CommonPermission',
],
}
-局部禁用:
class BookDetailView(ViewSetMixin, RetrieveAPIView):
permission_classes = []
3 频率组件
# 控制某个接口访问频率(次数)
# 查询所有接口,同一个ip一分钟只能访问5次
3.1 使用步骤
# 1 写一个频率类,继承SimpleRateThrottle
# 2 重写get_cache_key方法,返回什么,就以什么做限制----》ip,用户id做限制
# 3 配置一个类属性:scope = 'book_5_m'
# 4 在配置文件中配置
'DEFAULT_THROTTLE_RATES': {
'book_5_m': '5/m',
},
# 5 局部使用和全局使用
-局部:只在某个视图类中使用【当前视图类管理的所有接口】
class BookDetailView(ViewSetMixin, RetrieveAPIView):
throttle_classes = [CommonThrottle]
-全局:全局所有接口都生效
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],
}
-局部禁用:
class BookDetailView(ViewSetMixin, RetrieveAPIView):
throttle_classes = []
4 过滤排序
# restful规范中 要求了 请求地址中带过滤条件
-5个接口中, 只有一个接口需要有过滤和排序 查询所有接口
# 查询 所有图书接口 查询以 圣 开头的所有图书
4.0 继承APIView (伪代码)
class BookView(APIView):
def get(self, request):
search=request.query_params.get('search')
books=Book.objects.filter()
4.1内置过滤类的使用 【继承GenericAPIView】
from rest_framework.filters import SearchFilter
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerialize
# SeachFilter内置的 固定用法 模糊匹配
# 过滤功能 指定哪个字段过滤
filter_backends = [SearchFilter]
# 可以使用的搜索方式
http://127.0.0.1:8000/api/v1/books/?search=红 # name或price中只要有红就会搜出来
4.3 自己定制过滤类实现过滤
# 查询价格大于100的所有图书
http://127.0.0.1:8000/api/v1/books/?price_gt=100
#第一步; 定义一个过滤类,继承BaseFilterBackend,重写filter_queryset方法
class CommonFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
# 在里面实现过滤,返回qs对象,就是过滤后的数据
price_gt = request.query_params.get('price_gt', None)
if price_gt:
qs = queryset.filter(price__gt=int(price_gt))
return qs
else:
return queryset
# 第二步: 配置在视图类上
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [CommonFilter] # 可以定制多个,从左往右,依次执行
4.4排序的使用
# 内置的就够了
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [OrderingFilter]
ordering_fields = ['price']
# 支持的查询方法:
http://127.0.0.1:8000/api/v1/books/?ordering=price
http://127.0.0.1:8000/api/v1/books/?ordering=-price
http://127.0.0.1:8000/api/v1/books/?ordering=-id,price
5 分页
# 分页,只有查询所有接口,才有分页
# drf内置了三个分页器,对应三种分页方式
#内置的分页类不能直接使用,需要继承,定制一些参数后才能使用
# 分页使用,自定义一个分页类(三种)
class CommonPageNumberPagination(PageNumberPagination):
page_size = 2 # 每页显示2条
page_query_param = 'page' # page=10 查询第10页的数据,每页显示2条
page_size_query_param = 'size' # page=10&size=5 查询第10页,每页显示5条
max_page_size = 5 # 每页最大显示10条
# LimitOffset
class CommonLimitOffsetPagination(LimitOffsetPagination):
default_limit = 3 # 每页显示2条
limit_query_param = 'limit' # limit=3 取3条
offset_query_param = 'offset' # offset=1 从第一个位置开始,取limit条
max_limit = 5
# offset=3&limit=2 0 1 2 3 4 5
# app 用下面
class CommonCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 查询参数
page_size = 2 # 每页多少条
ordering = 'id' # 排序字段
# 配置在视图类上即可
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
authentication_classes = []
throttle_classes = []
# 之前的东西一样用 ,内置的分页类不能直接使用,需要继承,定制一些参数后才能使用
# pagination_class = PageNumberPagination
#基本分页方式(基本是这种,网页端):http://127.0.0.1:8000/api/v1/books/?page=2&size=3
# pagination_class = LimitOffsetPagination
# 偏移分页 http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1
# 从第一条开始,取4条
pagination_class = CommonCursorPagination
# 游标分页,只能下一页,上一页,不能跳到中间,但它的效率最高,大数据量分页,使用这种较好
标签:登录,ViewSetMixin,接口,token,books,class,drf
From: https://www.cnblogs.com/wei0919/p/17100015.html