Django Rest Framework:多次调用“ get_serializer_class”,请求方法的值错误 [英] Django Rest Framework: `get_serializer_class` called several times, with wrong value of request method
问题描述
使用 ModelViewSet
时,访问单个请求多次调用 get_serializer_class
是正常的吗?可浏览的API?并且 self.method.request
的值在每次调用之间都会改变?
Using a ModelViewSet
, is it normal for get_serializer_class
to be called multiple times for a single request, when accessing the browsable API? And that the value of self.method.request
changes between each call?
我创建了一个显示该行为的小型测试项目。在 project / example / views.py
有一个 ThingViewSet
和一个自定义的 get_serializer_class
,它会打印当前的请求方法。
I've created a small test project to show the behaviour. In project/example/views.py
there's a ThingViewSet
with a custom get_serializer_class
, which prints the current request method.
如果启动服务器并导航到 http://127.0.0.1:8000/things/1/ ,输出将类似于:
If you start the server and navigate to http://127.0.0.1:8000/things/1/, the output will be something like:
./manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
May 19, 2015 - 08:51:34
Django version 1.8.1, using settings 'project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Method is: GET
Method is: PUT
Method is: PATCH
Method is: PUT
[19/May/2015 08:51:40]"GET /things/1/ HTTP/1.1" 200 11679
很显然, get_serializer_class
被调用4次,具有不同的值( GET
, PUT
, PATCH
, PUT
),尽管仅执行一个 GET
请求。
Clearly, get_serializer_class
is called 4 times, with different values (GET
, PUT
, PATCH
, PUT
), although only a single GET
request is performed.
奇怪的是,如果您将其请求为JSON,则不会发生这种情况:
Strange thing is, that this doesn't happen if you request it as JSON:
./manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
May 19, 2015 - 10:25:57
Django version 1.8.1, using settings 'project.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Method is: GET
[19/May/2015 10:26:22]"GET /things/?format=json HTTP/1.1" 200 49
问题在于,上次调用可浏览API的 get_serializer_class
的请求方法是 PUT
(对于 GET
请求显然是错误的),然后我们最终为请求使用了错误的序列化程序,鉴于为不同的请求方法返回了不同的序列化程序,我们在现实生活中的项目中会这样做(例如,用于读取和写入操作)。
And the problem is that the request method in the last call to get_serializer_class
of the browsable API is PUT
(which is obviously wrong for a GET
request) and then we end up using the wrong serializer for the request, given that different serializers are returned for different request methods, which we do in our real life project (e.g. for read and write operations).
有人可以阐明什么吗?正在进行?为什么对于可浏览的API多次调用 get_serializer_class
并使用错误的方法值?
Can anybody shed some light on what is going on? Why is get_serializer_class
called several times for the browsable API, with wrong method values?
推荐答案
看到多次调用 get_serializer_class
的原因是因为您使用的是可浏览的API。如果您在不使用可浏览API的情况下进行了测试,例如通过强制JSON渲染器(?format = json
或 Accept $ c $
The reason why you are seeing get_serializer_class
being called multiple times is because you are using the browsable API. If you test it out without using the browsable API, for example by forcing the JSON renderer (?format=json
or an Accept
header), you will only see it called one.
可浏览的API会生成基于序列化程序显示的表单,因此 get_serializer_class
会为每种表单和可能的请求类型调用一次。
The browsable API generates the forms that are displayed based on the serializer, so get_serializer_class
is called once for each form and possible request type.
因此,在第一个请求中, GET
对于用于处理响应数据的原始序列化程序(在本例中为特定对象)有意义,接下来的三个是可浏览API的自定义项。这些是按照以下顺序发生的调用,您会看到 get_serializer
So while the first request, a GET
makes sense for the original serializer that is used to handle the response data (the specific object, in this case), the next three are custom to the browsable API. These are the calls that happen, in the following order, to get_serializer
which you are seeing
- The raw PUT form (for entering any request body).
- The raw PATCH form.
- The full PUT form (contains the instance data by default).
方法
已通过 override_method
与功能模拟请求的方法被覆盖,通常会在需要不同方法的 POST
请求中发生。
The method
is being changed with the override_method
with function which emulates the request method being overridden, which would normally happen in a POST
request that needed a different method.
这篇关于Django Rest Framework:多次调用“ get_serializer_class”,请求方法的值错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!