Django Rest Framework:`get_serializer_class` 多次调用,请求方法的值错误
Django Rest Framework: `get_serializer_class` called several times, with wrong value of request method
使用ModelViewSet
,当访问可浏览的API时,get_serializer_class
被单个请求多次调用是否正常? self.method.request
的值在每次调用之间发生变化?
我创建了 a small test project to show the behaviour. In project/example/views.py
有一个带有自定义 get_serializer_class
的 ThingViewSet
,它打印当前请求方法。
如果您启动服务器并导航到 http://127.0.0.1:8000/things/1/,输出将类似于:
./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
请求已执行。
奇怪的是,如果您以 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
请求来说显然是错误的) 然后我们最终为请求使用了错误的序列化器,因为我们在实际项目中(例如,读取和写入操作)为不同的请求方法返回了不同的序列化器。
任何人都可以阐明正在发生的事情吗?为什么 get_serializer_class
多次调用可浏览的 API,方法值错误?
您看到 get_serializer_class
被多次调用的原因是因为您使用的是可浏览的 API。如果您在不使用可浏览的 API 的情况下对其进行测试,例如通过强制 JSON 渲染器(?format=json
或 Accept
header),您将只会看到它叫一个。
可浏览的 API 生成基于序列化器显示的表单,因此 get_serializer_class
为每个表单和可能的请求类型调用一次。
因此,虽然第一个请求 GET
对于用于处理响应数据的原始序列化程序有意义(在本例中为特定的 object),但接下来的三个是自定义的到可浏览的 API。这些是按以下顺序对您看到的 get_serializer
进行的调用
- The raw PUT form (for entering any request body).
- The raw PATCH form.
- The full PUT form (contains the instance data by default).
method
正在更改为 the override_method
with function,它模拟被覆盖的请求方法,这通常发生在需要不同方法的 POST
请求中。
使用ModelViewSet
,当访问可浏览的API时,get_serializer_class
被单个请求多次调用是否正常? self.method.request
的值在每次调用之间发生变化?
我创建了 a small test project to show the behaviour. In project/example/views.py
有一个带有自定义 get_serializer_class
的 ThingViewSet
,它打印当前请求方法。
如果您启动服务器并导航到 http://127.0.0.1:8000/things/1/,输出将类似于:
./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
请求已执行。
奇怪的是,如果您以 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
请求来说显然是错误的) 然后我们最终为请求使用了错误的序列化器,因为我们在实际项目中(例如,读取和写入操作)为不同的请求方法返回了不同的序列化器。
任何人都可以阐明正在发生的事情吗?为什么 get_serializer_class
多次调用可浏览的 API,方法值错误?
您看到 get_serializer_class
被多次调用的原因是因为您使用的是可浏览的 API。如果您在不使用可浏览的 API 的情况下对其进行测试,例如通过强制 JSON 渲染器(?format=json
或 Accept
header),您将只会看到它叫一个。
可浏览的 API 生成基于序列化器显示的表单,因此 get_serializer_class
为每个表单和可能的请求类型调用一次。
因此,虽然第一个请求 GET
对于用于处理响应数据的原始序列化程序有意义(在本例中为特定的 object),但接下来的三个是自定义的到可浏览的 API。这些是按以下顺序对您看到的 get_serializer
进行的调用
- The raw PUT form (for entering any request body).
- The raw PATCH form.
- The full PUT form (contains the instance data by default).
method
正在更改为 the override_method
with function,它模拟被覆盖的请求方法,这通常发生在需要不同方法的 POST
请求中。