继续昨天的DRF解析器讲。
昨天我们说到我们CourseView视图类继承了APIView,当我们发送post请求时,接受不同的格式编码的数据,通过request.data能够拿到不同编码格式的数据,我们来看一下他的源码是怎么走的。
先说明DRF支持三种格式编码的解析,from rest_framework.parsers import JSONParser,FormParser,MultiPartParser
点进去源码我们可以看到DRF中的解析器,默认支持三种:JSONParser,FormParser,MultiPartParser
源码部分:
当我们发送post请求时,request.data会在这一步进行解析数据。 所以关键的地方在.data部分。data是request的静态方法。所以我们找源码的时候应该找request中的静态方法data。我们都知道这个request是在APIView中的dispatch方法重新封装了。所以应该去APIVew中找dispatch方法,需要找到request怎么被重新封装的。
点进源码:
点进Resquest源码,找data静态方法:
这一步就是数据解析的过程,点进去源码,
点进源码:
点进源码self.parser,
这就又回到实例化request的时候了。
点进去源码:
这里这个self,一层一层往上找,就找到了这个self.指的是视图类函数。所以在试图类函数中,定义了哪些解析器,他就支持哪些解析器。
那如果在我们的试图类函数中没有定义这个变量,那他是怎么走默认的解析器?
那我们点进parser_classes源码:
当我们点进api_settings中发现,api_settings是一个类的实例化对象,
但是在这个类中并没有DEFAULT_PARSER_CLASSES方法。
这里查一个知识点,在python基础中,一个类实例化后会进行初始化,执行__init__方法,但对于实例化没有的属性会走__getattr__方法。
所以,没有DEFAULT_PARSER_CLASSES方法,会走__getattr__方法,
而在我们的DEFAULTS中有DEFAULT_PARSER_CLASSES,
接下来:
点进去settings,找REST_FRAMEWORK,找不到就去全局settings中找。找不到就去默认字典字典中找,如果还是找不到,就赋值为空字典。
在最后的val就是 JSONParser,FormParser,MultiPartParser
这就是DRF默认的那三种解析器。
这就是解析器的源码。。。。。。
2.序列化组件
用序列化组件去写接口。
我们访问CourseView视图的时候,get请求使用我们自己写的json数据的方式,比较麻烦。
现在我们换一种方法,
我们先来说一种响应方式,这是rest_framework提供的响应方式
from rest_framework.response import Response 在return的时候,就不用写HttpResponse,写成return Response()。
使用这种相应方式,要在setting中注册app ,'rest_framework',然后用浏览器的方式请求。
然后我们来说第二种方式发送get请求:
class CourseView(APIView): def get(self,request): #查看所有数据 #方式一 course_list = Course.objects.all() # ret = [] # for course in course_list: # ret.append({ # "title":course.title, # "desc":course.desc, # }) # return HttpResponse(json.dumps(ret,ensure_ascii=False)) # 方式二 from django.core.serializers import serialize #django的序列化组件 data = serialize('json',course_list) return Response(data)
这就是第二种方法,很简单,但是我们依然不用他,关键在于他只是一个序列化组件,而我们的restframework不管可以做序列化,它还可以做校验的功能,保存记录的功能。
然后我们说第三种方式,restframework序列化组件
这就是get请求接口。
接下来我们来写post接口。
我们另外举个例子:
先多建几张表。BOOK表 , PUBLISH表 ,Author表,
如果想显示出版社的邮箱和出版社名字该怎么做呢?
对于多对多的字段就不能这样写了:
然后是post请求,
类比于form,form有一个modelform,他不用我们写form的那些复杂的字段,同样的serializer也有modelserializer,他也不用我们写那些复杂的字段。
所以我们把那个序列化类写成modelserializer,其他的东西都不用改。
这样post和get请求的接口就做完了
restful使用不同的请求方式去做url的分支
GET
books-------->查看数据--------------------> 返回所有数据列表 :[{},{},{}]
POST
books-------->添加数据--------------------->返回添加数据 :{}
PUT
books/1------->更新pk=1的数据--------------->返回更新后的数据: {}
Delete
books/1-------> 删除pk=1的数据-------------->返回空
GET
books/1------->查看单条数据 --------------->返回查看的单条数据 {}