Django REST Framework - 405 МЕТОД НЕ ДОПУСКАЕТСЯ с использованием SimpleRouter

Я использую SimpleRouter tuorial в документах.

Просто чтобы проверить, я создал временный класс проверки подлинности:

class BackboneBasicAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        user = User.objects.filter(username="james")
        return (user, None)
Настройки

выглядят следующим образом:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'core.rest_authentication.BackboneBasicAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
       'rest_framework.permissions.AllowAny',
    ),
}

Отправка запроса PUT возвращает 405 МЕТОД НЕ ДОПУСКАЕТСЯ

{"detail": "Method 'PUT' not allowed."}

Я тоже пробовал с X-HTTP-методом-переопределить. Нет.

Любые идеи, что я делаю неправильно?

Я потратил целый день, пытаясь понять это, надеюсь, кто-то может помочь!:)

Ответ 1

Мне кажется, что это вызвано маршрутизированным просмотром, не реализующим или не разрешающим запросы PUT. Если это проблема аутентификации, вы получите код состояния 401 UNAUTHORIZED.

Ответ 2

Простой маршрутизатор добавляет атрибут put в представление для URL-адреса, сопоставляющего шаблон, который вы поставляете, с добавлением pk в качестве дополнительного элемента шаблона.

Например, если вы использовали:

simple_router.register('widgets/', WidgetViewSet)

Структура создаст два шаблона url:

'^widgets/$'
'^widgets/<?P<pk>[^/]+/$'

Я предполагаю, что вы только пытаетесь использовать URL-адреса, которые удовлетворяют первому совпадению, для которого экземпляр viewset будет иметь поддержку "get" ( "list" ) и "post" ( "create" ), добавленную каркасом, так что это будет вы вызываете ошибку, которую видите, если пытаетесь установить/исправить или удалить. Для этих методов вам необходимо предоставить pk, чтобы структура знала, какой виджет вы изменяете или удаляете, и чтобы ваш URL-адрес соответствовал представлению, поддерживающему эти методы.

Это сбивает с толку, и вы можете вообще не использовать simple_router, если вы считаете его слишком запутанным. Затем вы можете указать собственное сопоставление методов, чтобы rest_framework отправил ваши методы put, например.

url('^widgets/<?P<pk>[^/]+/$', WidgetViewSet.as_view({'put': 'update', 
                                                      'get': 'retrieve', 
                                                      'patch': 'partial_update', 
                                                      'delete': 'destroy'}...)