Реализация методов HTTP в различных классах APIView в django
У меня есть API с 2 маршрутами some_resource/
и some_resource/<id>
и я хотел бы реализовать обычные CRUD действия (list, retrieve, create, update, delete). Однако я не хочу использовать ViewSet, потому что хочу иметь 1 класс для каждого представления. Таким образом, мне нужно настроить маршрут вручную для ясности :
class SomeResourceRetrieveView(APIView):
def get(self, request, pk, *args, **kwargs):
...
class SomeResourceListView(APIView):
def get(self, request, *args, **kwargs):
...
class SomeResourceCreateView(APIView):
def post(self, request, *args, **kwargs):
...
Так что в urls.py это выглядит следующим образом
url_patterns = [
path("some_resource/", InvitationTeamAccessListAPI.as_view(), name="some-resource-list"),
path("some_resource/", InvitationTeamAccessCreateAPI.as_view(), name="some-resource-create"),
path("some_resource/<int:pk>", InvitationTeamAccessRetrieveAPI.as_view(), name="some-resource-retrieve"),
]
Однако когда я использую POST на some_resource/
, я получаю 405. Я думаю, что django останавливается на первом подходящем маршруте и не находит реализации для post. Есть ли способ подключить все мои представления к одному шаблону, но сохранить их как отдельные классы?
Вы можете использовать ViewSets
попробуйте следующее:
from rest_framework import viewsets
from rest_framework.response import Response
class InvitationTeamAccessViewSet(viewsets.ViewSet):
"""
Example empty viewset demonstrating the standard
actions that will be handled by a router class.
If you're using format suffixes, make sure to also include
the `format=None` keyword argument for each action.
"""
def list(self, request):
# this is your get() method
queryset = InvitationTeamAccess.objects.all()
# you should change your serializer name accordingly
serializer = InvitationTeamAccessSerializer(queryset, many=True)
return Response(serializer.data)
def create(self, request):
# this is your post method
# you have to write you post logic here
pass
def retrieve(self, request, pk=None):
# this is your get() details method
queryset = InvitationTeamAccess.get(pk=pk)
# you should change your serializer name accordingly
serializer = InvitationTeamAccessSerializer(queryset)
return Response(serializer.data)
def update(self, request, pk=None):
# write your post() method here
pass
def partial_update(self, request, pk=None):
pass
def destroy(self, request, pk=None):
pass
и в urls.py
from myapp.views import InvitationTeamAccess
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'some_resource/', InvitationTeamAccess, basename='InvitationTeamAccess')
urlpatterns = router.urls
тогда с помощью одного пути url вы можете выполнить несколько действий
GET: some_resource/ покажет список InvitationTeamAccess'ов
. GET: some_resource/1/ покажет детали одного InvitationTeamAccess
. POST: some_resource/ создаст новый InvitationTeamAccess
также читайте о ModelVieset