Django Rest Framework: "get serializer class" вызывается несколько раз, с неправильным значением метода запроса

С помощью ModelViewSet, это нормально get_serializer_class вызываться несколько раз для одного запроса при доступе к просматриваемому API? И что значение self.method.request изменения между каждым вызовом?

я создал небольшой тестовый проект, чтобы показать поведение. В project/example/views.py здесь ThingViewSet с пользовательским get_serializer_class, который печатает текущий метод запроса.

если вы запустите сервер и перейдите к 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), хотя только один запрос.

странно, что этого не происходит, если вы запрашиваете его как 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

и проблема в том, что метод запроса в последний вызов get_serializer_class из просматриваемого API является PUT (что, очевидно, неправильно для GET запрос), а затем мы в конечном итоге используем неправильный сериализатор для запроса, учитывая, что разные сериализаторы возвращаются для разных методов запроса, что мы делаем в нашем реальном проекте (например, для операций чтения и записи).

может кто-нибудь пролить свет на происходящее? Почему это get_serializer_class вызывается несколько раз для просматриваемого API с неправильными значениями метода?

1 ответов


причина, по которой вы видите get_serializer_class вызывается несколько раз, потому что вы используете просматриваемый API. Если вы протестируете его без использования просматриваемого API, например, заставив JSON renderer (?format=json или Accept заголовок), вы увидите только один.

просматриваемый API генерирует формы, которые отображаются на основе сериализатора, поэтому get_serializer_class вызывается один раз для каждой формы и возможный тип запроса.

Итак, пока первый запрос, a GET имеет смысл для исходного сериализатора, который используется для обработки данных ответа (конкретный объект, в этом случае), следующие три являются пользовательскими для просматриваемого API. Это вызовы, которые происходят в следующем порядке:get_serializer которых вы видите

  1. необработанная форма PUT (для ввода любого тела запроса).
  2. необработанная форма патча.
  3. полная форма PUT (содержит данные экземпляра по неисполнение.)

на method изменяется с на override_method С функцией который эмулирует переопределяемый метод запроса, что обычно происходит в POST запрос что нужен другой способ.