Django Rest Framework:多次调用“ get_serializer_class”,请求方法的值错误 [英] Django Rest Framework: `get_serializer_class` called several times, with wrong value of request method

查看:810
本文介绍了Django Rest Framework:多次调用“ get_serializer_class”,请求方法的值错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 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

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


  1. 原始PUT表单(用于输入任何请求正文)。 / a>

  2. 原始修补程序表单。

  3. 完整的PUT表单(默认情况下包含实例数据)。

  1. The raw PUT form (for entering any request body).
  2. The raw PATCH form.
  3. 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆