drf之过滤排序分页异常处理
1 drf回顾
# 入门规范
-前后端开发模式
-API接口
-接口测试工具-postman
-restful规范(10条)
-drf快速入门 (django的app,只能django框架使用)
-drf最新版,最低支持django 2.x以上
# 序列化组件
-queryset对象:orm查询多个结果就是qs对象
-把对象(qs)对象转成字典 many=True
-把前端传入的json格式字符串,转成对象保存
-Serializer 和 ModelSerializer
- serializer = StudentSerializer(instance=student)
- serializer.data---->就是序列化后的字典
-字段(CharField,IntegerField)
-字段属性(read_only,write_only)
-反序列化
-新增
-serializer = StudentSerializer(data=request.data)
-serializer.save() # Serializer重写create,ModelSerializer不需要重写
-修改
-serializer = StudentSerializer(instance=对象,data=request.data)
-serializer.save() # Serializer重写updata,ModelSerializer不需要重写
-数据校验(反序列化)
-字段自己的校验规则
-钩子函数
# 请求和响应
-Request对象:新的request
-request.data
-request.query_params
-request.xx # 就是原来request对象的属性
-处理什么格式的请求(urlencode,form-data,json)
-全局配置
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser', # json
'rest_framework.parsers.FormParser', # urlencoded
'rest_framework.parsers.MultiPartParser',# form-data
],
}
-局部配置
class BookView(APIView):
parser_classes = [JSONParser]
## 新手四件套
obj=HttpResonose()
obj=render--->函数,打开模板,去做替换(模板语法dtl),生成一个HttpResonose的对象
obj=redirect--》生成一个HttpResonose的对象
obj=JsonResponse--》生成一个HttpResonose的对象
obj['xx']=xx # 向响应头写数据
-Response对象
-from rest_framework.response import Response
-data=None, 响应的数据,字典,字符串
-status=None, 响应状态码,1,2,3,4,5
-headers={'xx':'xx'}, 响应头 (响应对象['xx']=xx)
-响应格式样子(json,浏览器访问的)
-全局配置
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器
)
}
-局部配置
class BookView(APIView):
render_classes = [JSONRenderer]
# 视图
-2个视图基类
-APIView
-GenericAPIView
-queryset类属性
-serializer_class类属性
-ser=get_serializer(instance=对象,many=True) 方法
-get_queryset(self) 方法
-get_object(self)方法
-5个视图扩展类(不是视图类),每个类就写了一个方法,需要配合上面两个使用
-CreateModelMixin
-ListModelMixin
-RetrieveModelMixin
-UpdateModelMixin
-DestroyModelMixin
-9个视图子类
-视图集
-ModelViewSet
-ReadOnlyModelViewSet
-ViewSetMixin 类,没有集成任何类--》写了一个方法as_view---》路由写法变了---》自动生成路由
-ViewSet:APIView与ViewSetMixin
-GenericViewSet:GenericAPIView与ViewSetMixi
# 路由
-继承ViewSetMixin及子类,路由写法变了
-url(r'^books/(?P<pk>\d+)/$', BookInfoViewSet.as_view({'get': 'retrieve'})
-自动生成路由
-SimpleRouter(用的多)
-DefaultRouter
-from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'router_stu', StudentModelViewSet, base_name='student')
-urlpatterns += router.urls
-url(r'^', include(router.urls))
-action装饰器
@action(methods=['get'], detail=False)
def login(self, request):
# 三大认证()
-认证(判断是否登录)
-写一个认证类,继承BaseAuthentication,重写authenticate
-在authenticate中认证,认证通过返回None或者两个值
-局部使用和全局使用
-权限(登录成功,是否能访问接口)
-写一个类,继承BasePermission,重写has_permission方法,有权限,返回True,没有权限,返回False
-局部和全局使用
-频率(根据ip,根据用户限制每分钟只能访问多少次)
-#写一个类,继承自SimpleRateThrottle,(根据ip限制)
from rest_framework.throttling import SimpleRateThrottle
class VisitThrottle(SimpleRateThrottle):
scope = 'luffy'
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR') # 返回什么,就以什么限制
#在setting里配置:(一分钟访问三次)
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES':{
'luffy':'3/m' # key要跟类中的scop对应
}
}
-局部和全局使用
2 过滤排序分页异常处理
2.1 过滤
# 只针对于查询所有接口
# 127.0.0.1:8000/four/students/?sex=1
# 方式一:笨办法
def list(self, request, *args, **kwargs):
query=request.GET.get('name')
qs=self.get_queryset().filter(name=query)
ser=self.get_serializer(instance=qs,many=True)
return Response(ser.data)
# 方式二:使用内置的过滤类(可以自己写,使用第三方)
filter_backends=[SearchFilter,] ## 过滤类:可以自己写,也可以用内置,使用第三方
# SearchFilter类中通过反射获取的字段
search_fields=['name','publish'] # 按那个字段过滤,可以模糊匹配
# http://127.0.0.1:8000/book/?search=条件 并且支持模糊匹配
2.1 排序
# class BookView(ViewSetMixin, ListAPIView):
# queryset = Book.objects.all()
# serializer_class = BookSerializer
#
# ### 方法一:笨办法
# # def list(self, request, *args, **kwargs):
# # query=request.query_params.get('ordering')
# # qs = self.get_queryset()
# # if query:
# # qs=qs.order_by(query)
# # ser=self.get_serializer(instance=qs,many=True)
# # return Response(ser.data)
#
# ### 方式二:
# filter_backends = [OrderingFilter] # 内置的排序类
# ordering_fields=['price']
# # http://127.0.0.1:8000/book/?ordering=price
# # http://127.0.0.1:8000/book/?ordering=-price
### 排查过滤连用
# class BookView(ViewSetMixin, ListAPIView):
# queryset = Book.objects.all()
# serializer_class = BookSerializer
#
# ### 方式:
# filter_backends = [SearchFilter,OrderingFilter] # 放在第一位的,最好能优先过滤掉很多数据
# ordering_fields=['price']
# search_fields = ['publish']
# # http://127.0.0.1:8000/book/?ordering=price
# # http://127.0.0.1:8000/book/?ordering=-price
2.3 自定义过滤类
# 第一步,写一个类,继承基类BaseFilterBackend,重写某个方法filter_queryset,返回的数据就是过滤后的qs对象
# 配置一下,在视图类中配置
filter_backends = [FilterByName]
### 过滤类
from rest_framework.filters import BaseFilterBackend
class FilterByName(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
#http://127.0.0.1:8000/book/?name=红楼梦
query=request.query_params.get('name')
if query:
return queryset.filter(name__contains= query )
else:
return queryset
return queryset
### 视图类
# from .filters import FilterByName
# class BookView(ViewSetMixin, ListAPIView):
# queryset = Book.objects.all()
# serializer_class = BookSerializer
# filter_backends = [FilterByName]
2.4 django-filter的简单使用
## 使用第三方:django-filter,需要安装 pip3 install django-filter
# 是一个app,需要在项目中注册
# 导入django-filter提供的过滤类
from django_filters.rest_framework import DjangoFilterBackend
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [DjangoFilterBackend,]
filter_fields=['name','publish'] # 不支持模糊匹配,只支持精准匹配,多个搜索条件是and关系
如果需要修改and关系,可以使用Q
2.5 分页的使用
必须继承GengericAPIView及其子类
# 重写类方法
# 三种分页方式,需要重写类属性
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
class MyPageNumberPagination(PageNumberPagination):
page_size = 2 # 每页显示的条数
page_query_param = 'p' #http://127.0.0.1:8000/book/?page=3
page_size_query_param = 's' # 每页显示多少条
max_page_size = 3 # 每页最大显示3条
class MyLimitOffsetPagination(LimitOffsetPagination):
default_limit = 1 # 每页显示的条数
limit_query_param = 'limit' # 取几条
offset_query_param = 'offset' # 标杆,从第几个位置开始取 默认情况,每页显示一条
max_limit = 5 # 最大每页显示多少条
# 分页速度快,有缺陷,只能上一页和下一页,不能直接跳到某一页,针对于数据量大,可以使用该分页方式
class MyCursorPagination(CursorPagination):
cursor_query_param = 'cursor' # 不用动,没有用
page_size = 3 # 每页显示多少条
ordering = 'id' # 游标分页的原理,是先排序,然后使用游标标志位置,只能往前,往后,所以只能上一页和下一页
#### 在视图类中使用
class BookView(ViewSetMixin, ListAPIView):
# 带分页功能
pagination_class = CursorPagination # 配置成你重写的类
# 全局使用
'DEFAULT_PAGINATION_CLASS': None,
3 自动生成接口文档
# 土一点的公司:纯手写(word,md)
# 高级一点的:自动生成(drf:coreapi,swagger)
# 最高级的:接口文档平台
-平台中录入:使用第三方
-Yapi:百度开源的,把swagger自动生成的直接导入,修改
# 第一步:安装coreapi
# 第二步:配置路由
from rest_framework.documentation import include_docs_urls
path('docs/', include_docs_urls(title='xx项目接口平台')),
# 第三步:配置文件中配置
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema',
}
# 第四步:写视图函数,在视图函数上加注释

浙公网安备 33010602011771号