1 编写登录接口,图书5大接口,实现图书5大接口匿名用户一分钟访问3次,登录用户一分钟访问10次
-方式一:
-写两个频率类(一个是根据ip限制,另一个根据userid)
-方式二:
-使用内置的,如果可以,就没问题就可以,如果又问题需要继承重写get_cache_key方法
2 一个接口既可以不登录访问,又可以登录访问(匿名用户一分钟访问3次,登录用户一分钟访问10次)
-认证类:额外写
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
res = models.UserToken.objects.filter(token=token).first()
if res:
return (res.user, token)
else:
return None
-登录用户的频率限制
class MySimpleThrottle(SimpleRateThrottle):
scope = 'xxx'
def get_cache_key(self, request, view):
if not request.user.id:# 没有登录用户
return self.get_ident(request) #根据ip限制
else:
return None
-未登录用户的频率限制
class MyLoginThrottle(SimpleRateThrottle):
scope = 'login'
def get_cache_key(self, request, view):
return request.user.pk
-排序(内置排序规则)
-在视图类中配置
filter_backends =[OrderingFilter,]
ordering_fields=['id','age']
-查询:
http://127.0.0.1:8000/students/?ordering=-age
-过滤(内置)
-在视图类中配置
filter_backends =[SearchFilter,]
search_fields=('name','age')
-查询:
http://127.0.0.1:8000/students/?search=9,l
-过滤(django-filter)
-在视图类中配置
filter_backends =[DjangoFilterBackend,]
filter_fields=['name','age']
-查询:
http://127.0.0.1:8000/students/?name=lqz&age=10
-自定制过滤器
-查询所有才会有过滤---》list才需要过滤---》queryset = self.filter_queryset(self.get_queryset())---》GenericAPIView-->filter_queryset
def filter_queryset(self, queryset):
for backend in list(self.filter_backends):
queryset = backend().filter_queryset(self.request, queryset, self)
return queryset
0 自定制过滤器
基于django-filter扩写
1 写一个类MyFilter,继承BaseFilterBackend
2 重写filter_queryset方法,在该方法内部进行过滤(自己设置的过滤条件)
3 返回queryset对象(过滤后的queryset对象)
4 配置在视图类中
filter_backends = [MyFilter,]
1 分页器(三种)重点如何使用
1 内置了三种分页器
-PageNumberPagination:普通分页
-LimitOffsetPagination:偏移分页
-CursorPagination:游标分页
2 APIView和GenericAPIView+ListModelMixin
3 GenericAPIView+ListModelMixin的分页模式
4 PageNumberPagination:普通分页(用的最多)
-page_size = api_settings.PAGE_SIZE # 每页显示多少条
-page_query_param = 'page' # 查询参数
-page_size_query_param = size # 查询的时候指定每页显示多少条
-max_page_size = 10 # 每页最多显示多少条
-使用方式:
-定义一个类,继承PageNumberPagination
-重写四个属性
-在继承了GenericAPIView+ListModelMixin视图类中配置
pagination_class = MyPageNumberPagination
-查询
http://127.0.0.1:8000/students/?page=1&size=5
5 LimitOffsetPagination:偏移分页
-default_limit = api_settings.PAGE_SIZE # 默认条数
-limit_query_param = 'limit' # 查询时,指定查询多少条
-offset_query_param = 'offset' # 查询时,指定的起始位置是哪
-max_limit = None # 查询时,最多返回多少条
-使用方式:
-定义一个类,继承LimitOffsetPagination
-重写四个属性
-在继承了GenericAPIView+ListModelMixin视图类中配置
pagination_class = MyPageNumberPagination
-查询
http://127.0.0.1:8000/students/?limit=100&offset=1
6 CursorPagination:游标分页(速度块)
-cursor_query_param = 'cursor' # 查询的时候,指定的查询方式
-page_size = api_settings.PAGE_SIZE # 每页显示多少条
-ordering = '-created' # 排序方式
-page_size_query_param = size # 查询的时候指定每页显示多少条
-max_page_size = None #每页最多显示多少条
-使用方式:
-定义一个类,继承LimitOffsetPagination
-重写四个属性
-在继承了GenericAPIView+ListModelMixin视图类中配置
pagination_class = MyPageNumberPagination
-查询
http://127.0.0.1:8000/students/?limit=100&offset=1
7 APIView的分页模式
-新建一个类,继承普通分页,重写四个属性
-视图类写法如下
class StudentApiView(APIView):
def get(self,request):
student_list=Student.objects.all()
page=MyPageNumberPagination()# 实例化得到对象
# 只需要换不同的分页类即可
res=page.paginate_queryset(student_list,request,self)# 开始分页
ser=StudentSerializer(res,many=True)
return page.get_paginated_response(ser.data) # 返回数据
2 全局异常
1 统一接口的返回方式,即便视图函数执行出错
2 使用方式
-写一个函数
def common_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is None:
response = Response({'code':999,'detail': '未知错误'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return response
-在setting中配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER':'app01.utils.common_exception_handler'
}
3 封装Response对象
1 以后都使用自己封装的response
class APIResponse(Response):
def __init__(self, code=100, msg='成功', data=None, status=None, headers=None, content_type=None, **kwargs):
dic = {'code': code, 'msg': msg}
if data:
dic['data'] = data
dic.update(kwargs) # 这里使用update
super().__init__(data=dic, status=status,
template_name=None, headers=headers,
exception=False, content_type=content_type)
2 使用:
return APIResponse(code=100,msg='查询成功',data=ser.data,count=200,next='http://wwwa.asdfas')
4 自动生成接口文档
1 借助于第三方:coreapi,swagger
2 在路由中
from rest_framework.documentation import include_docs_urls
path('docs/', include_docs_urls(title='图书管理系统api'))
3 在配置文件中
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
4 写视图类(需要加注释)
class BookListCreateView(ListCreateAPIView):
"""
get:
返回所有图书信息.
asdfasfda
post:
新建图书.
"""
queryset = Student.objects.all()
serializer_class = StudentSerializer
5 只需要在浏览器输入,就可以看到自动生成的接口文档()
http://127.0.0.1:8000/docs/