Реализация методов 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

Вернуться на верх