Поскольку ваши url_path
и detail
одинаковы в обоих случаях, зачем вам два разных метода в ваших представлениях ??
В любом случае, я бы порекомендовал этот способ,
class MobileDeviceViewset(ModelViewSet):
# your code
<b>@action(methods=['get', 'post', 'put', 'patch'], url_path='token', detail=True, )
def my_action(self, request, *args, **kwargs):
if request.method == 'GET':
return self.get_token(request, *args, **kwargs)
else:
return self.update_token(request, *args, **kwargs)</b>
def update_token(self, request, *args, **kwargs):
return Response("update token response--{}".format(request.method))
def get_token(self, request, *args, **kwargs):
return Response("update token response--{}".format(request.method))
Затем вам нужно внести некоторые изменения в конфигурацию вашего URL,
from django.urls import path
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
<b>router.register('mysample', MobileDeviceViewset, base_name='mobile-device')
actions = {
"get": "my_action",
"post": "my_action",
"put": "my_action",
"patch": "my_action"
}
urlpatterns = [
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls</b>
Следовательно, ваш URL будет выглядеть примерно так: ..../mysample/3/token/
ПРИМЕЧАНИЕ
Это решение протестировано под Python 3.6
, Django==2.1
и DRF==3.8.2
ОБНОВЛЕНИЕ
Почему Method Not Allowed
ошибка?
Когда в Django приходит запрос, он ищет шаблоны в конфигах URL и отправляет запрос в соответствующее представление в случае совпадения.
В вашем случае вы определили два представления (да .. хотя это действия) с одним и тем же URL (как показано ниже).
actions = {
"post": "update_token",
"put": "update_token",
"patch": "update_token"
}
urlpatterns = [
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions={"get": "get_token"})),
path('mysample/<pk>/token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls
В этом случае приходит запрос (пустьэто будет HTTP POST ), и диспетчер URL перенаправляет в первое представление , которое удовлетворяет пути URL.Итак, запрос POST входит в метод get_token
, но он разрешен только для метода GET
Что такоевозможное решение?
Метод-1:
Как я уже говорил выше, используйте общее действие и distingush для HTTP METHODS и вызывайте соответствующие методы
Метод 2:
Использовать разные пути URL для обоих действий, например
actions = {
"post": "my_action",
"put": "my_action",
"patch": "my_action"
}
urlpatterns = [
path('mysample/<pk>/get-token/', MobileDeviceViewset.as_view(actions={"get": "get_token"})),
path('mysample/<pk>/update-token/', MobileDeviceViewset.as_view(actions=actions))
] + router.urls