Django REST framwork之响应和请求格式配置,解析器,自动生成路由、action装饰器
作者:互联网
drf 响应格式和请求格式配置(了解)
配置响应格式
1 在配置文件中配置 REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( # 默认响应渲染类 'rest_framework.renderers.JSONRenderer', # json渲染器 'rest_framework.renderers.BrowsableAPIRenderer', # 浏览API渲染器 ) } 2 在浏览器访问就是浏览器方式,用postman访问就是json格式,ajax请求就是json格式 3 原来没有配置,为什么显示浏览器方式和json的样子 4 drf也有一套默认配置文件,默认就配了两个响应类 5 局部配置某个视图类的响应格式,在视图类中配置 renderer_classes = []
配置能够解析的格式(urlencoded,formdata,json)
什么是解析器?在DRF中,解析器是一个类列表,当每次接收到请求时,RDF会根据请求头中的Content-type,来指定使用哪钟解析方法去解析数据。当content-type与解析器列表均不匹配时,则会报解析失败。
1 在setting中配置解析器列表 REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ # 解析json格式数据({"user": "zhubao"}),解析成功后,request.data类型为dict 'rest_framework.parsers.JSONParser', # 解析form表单格式数据(user=zhubao),解析成功后,request.data类型为QuerySet 'rest_framework.parsers.FormParser', # (用的较少),解析较为复杂的form表单格式数据,解析成功后,request.data类型为QuerySet 'rest_framework.parsers.MultiPartParser' ] } 2 它就只能解析三种请求编码格式(urlencoded,formdata,json) 3 局部使用,在视图类中配置 from rest_framework.parsers import JSONParser, FormParser parser_classes = [FormParser]
需要注意的是,一般get请求中,请求头没有Content-type字段,请求体内也没有值,request.data是空字典,因此解析器也不会生效,解析器更多的是针对POST、PUT请求。
若settings.py与视图中均未设置解析器,DRF默认提供三种解析类,即:JSONParser, FormParser,MultiPartParser,每次请求根据Content-type来匹配使用哪种方式来解析。
封装自己的Response对象
low版本
# 封装 class MyResponse(): def __init__(self): self.status = 100 self.msg = None @property def get_dict(self): return self.__dict__ # 使用 #### 原来的写法 # class Test(APIView): # def get(self,request): # response={'status':'100','msg':None} # #写一堆逻辑 # response['data']={'name':'lqz','age':19} # response.data={} # # return Response(response) ###自己封装了low response后 from app01.response import MyResponse class Test(APIView): def get(self, request): response = MyResponse() # 写一堆逻辑 response.status=101 response.msg='失败了' response.data={'name': 'lqz', 'age': 19} return Response(response.get_dict)
高级版本
# 在app目录下手动创建response.py文件,名字随意 # 自定义一个APIResponse类,继承drf的Response from rest_framework.response import Response class APIResponse(Response): def __init__(self, code=100, msg=None, data=None, status=None, template_name=None, headers=None, exception=False, content_type=None, **kwargs): dic = {'status': code, 'msg': msg} if data: # 如果data有值,说明要往里面放东西 dic['data'] = data if kwargs: # 自定义传的参数会添加到字典里 dic.update(kwargs) super().__init__(data=dic, status=status, template_name=template_name, headers=headers, exception=exception, content_type=content_type) ### 使用,在视图类中
from app01.response import APIResponse # 先导入自定义的类
return APIResponse(msg='成功了',data={'name': 'lqz', 'age': 19},next=9)
drf自动生成路由
1 三种路由写法 - path('test/', views.Test.as_view()), -path('test/', views.Test.as_view({'get':'send_email'})), -自动生成路由
# 1 导入路由类 from rest_framework.routers import SimpleRouter, DefaultRouter # DefaultRouter生成的路由更多一点,多了一个根的路由(没有用) # 2 实例化得到对象 router = SimpleRouter() # 3 注册路由 router.register('books', views.BookView) # router.register('publish', views.PublishView) # print(router.urls) # 自动生成的路由 from django.contrib import admin from django.urls import path,include from app01 import views urlpatterns = [ # 4 用include把自动生成的路径加入到urlpatterns path('api/v1/', include(router.urls)), # path('api/v2', include(router.urls)) # path('admin/', admin.site.urls), # path('test/', views.Test.as_view()), # path('books/', views.BookView.as_view({'get': 'list', 'post': 'create'})), # path('books/<int:pk>', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})), ] # 4 把自动生成的路径加入到urlpatterns # urlpatterns+=router.urls # a=[1,2,3] # b=[4,5,6] # print(a+b)
重点:ViewSetMixin+9个视图字类才能用自动生成路由
对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
REST framework提供了两个router
- SimpleRouter
- DefaultRouter
DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。
添加路由数据
可以有两种方式:
urlpatterns = [ ... ] urlpatterns += router.urls
或
urlpatterns = [ ... url(r'^', include(router.urls)) ]
action装饰器
在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action
装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
1 作用:给自动生成路由的视图类再定制一些路由 methods 请求方式,detail是否带pk methods第一个参数,传一个列表,列表中放请求方式 2 用法一:detail布尔类型,detail=False # api/v1/books/sen_email/ @action(methods=['GET'], detail=False) def sen_email(self, request, *args, **kwargs): print(args) print(kwargs) return APIResponse(msg='发送成功') 3 方法二:detail布尔类型,detail=True # api/v1/books/1/sen_email/ @action(methods=['GET'], detail=True) def sen_email(self, request, *args, **kwargs): # pk=1 print(args) print(kwargs) return APIResponse(msg='发送成功')
drf知识回顾
1 drf入门 -web开发模式:分离和混合 -api接口:接口 -postman的使用(http客户端) -restful-10条规范 -drf是什么,能做什么(快速写符合resful规范的接口) -分析了执行流程:APIView -重写了dispatch -包装了新的request:drf的request -self.initial -请求格式处理,认证,权限,频率 -处理了全局异常 -处理了响应 -Request对象:data,取其他值和属性时跟原来一样 2 序列化器 -Serializer,ModelSerializer -写一个类继承Serializer -在类中写字段, -字段参数:read_only,write_only -视图类中使用:ser=Serilaizer(要序列化的对象,many=True) -ser.data -反序列化 -ser=Serilaizer(data=字典) -ser.is_valid() -ser.save():Serializer需要重写update和create -反序列化的修改 -ser=Serilaizer(instance=对象,data=字典) -ModelSerializer -class Meta: model=表模型 fields='__all__' extra_kwargs={'name';{}} -重写字段 name=serilaizer.CharField(source='xx') name=serilaizer.SerializerMethodField() def get_name(self,obj): return 'sb'+obj.name 子序列化 publish=PublishSerializer() 2.1 序列化类的源码 -many控制了谁 -局部钩子和全局钩子 -source为什么填publish.name 方法 3 请求和响应 -自己封装了一个响应对象(low,高级) -通过配置,配置请求和响应(全局配置,局部配置) 4 视图 -APIView,GenericAPIView -5个视图扩展类 -9个视图子类 -写一个删除接口(只需要继承DestroyAPIView,写上那两个类属性) -视图集 -ViewSetMixin:路由就不一样了 4.1 写一个删除接口,但是,删除后要记录日志 5 自动生成路由 -SimpleRouter -ViewSetMixin+9个子类视图才能自动生成路由 6 action装饰器 -自动生成路由后,使用action装饰器来继续让写在视图类的方法,可以被访问到
标签:解析器,name,self,framwork,视图,REST,data,response,路由 来源: https://www.cnblogs.com/gfeng/p/14674997.html