Как эффективно использовать HTTP-методы PUT и DELETE в Django Class-Based Views?

Я создаю CRUD-систему на Django, используя Class-Based Views. В настоящее время я пытаюсь понять, как обрабатывать HTTP PUT и DELETE запросы в моем приложении. Несмотря на обширный поиск в документации Django, мне трудно найти конкретные примеры и четкие объяснения того, как отправлять эти типы запросов в представление, основанное на классах.

Я создал класс представления CategoryView, расширяющийся из: django.views.View, в котором успешно реализовал методы get и post. И я хочу построить свои урлы следующим образом:

  1. Новая категория: 127.0.0.1:8000/backendapp/categories/create
  2. .
  3. Список всех категорий: 127.0.0.1:8000/backendapp/categories/
  4. Получить только одну категорию: 127.0.0.1:8000/backendapp/categories/1
  5. И т.д...

Однако, когда я пытаюсь реализовать методы put и delete, я застреваю.

Например :


from django.views import View

class CategoryView(View):
     template_name = 'backendapp/pages/category/categories.html'
    
     def get(self, request):
         categories = Category.objects.all()
        
         context = {
             'categories': categories
         }
        
         return render(request, self.template_name, context)
    
     def post(self, request):
         return
        
     def delete(self, request, pk):
         return
        
     def put(self, request):
         return

Я прочитал документацию Django и обнаружил, что Class-Based Views поддерживают HTTP-запросы: ["get", "post", "put", "patch", "delete", "head ", "options", "trace"]. ссылка: https://docs.djangoproject.com/en/5.0/ref/class-based-views/base/#django.views.generic.base.View

Несмотря на это, я не могу понять, как это сделать.

Поэтому я прошу вашей помощи, чтобы разблокировать меня.

Я изучил документацию Django и поискал в Интернете примеры и учебники по обработке HTTP-запросов в представлениях на основе классов. Я также попробовал поэкспериментировать с добавлением методов put и delete в свой класс представления CategoryView, но безуспешно. Я ожидал найти ресурсы, которые четко объясняют, как интегрировать эти запросы в мое Django-приложение, а также практические примеры, демонстрирующие их использование. Однако я не нашел рабочего решения и теперь прошу помощи у сообщества, чтобы преодолеть эту трудность.

Обратите внимание, что HTML не поддерживает PUT, PATCH, DELETE "из коробки". Вы можете использовать AJAX, но <form method="delete"> не будет работать, просто потому, что браузер не делает запрос DELETE. Поэтому вам понадобится AJAX, чтобы сделать этот запрос.

Другая проблема заключается в маршрутизации: ваше представление находится за categories/, поэтому именно там вы будете выполнять запросы PUT, PATCH и т. д. Таким образом, вам придется определить несколько представлений, каждое из которых будет обрабатывать часть запроса, например:

from django.urls import path

urlpatterns = [
    path('categories/', MyListlikeCategoryView.as_view()),
    path('categories/<int:pk>/', MyObjectlikeCategoryView.as_view()),
    path('categories/create/', MyCreateCategoryView.as_view()),
]

и затем в этих отдельных представлениях реализуйте применимые методы:

class MyListlikeCategoryView(View):
    # list of categories
    def get(self, request):
        # …
        pass


class MyObjectlikeCategoryView(View):
    # put new object
    def put(self, request, pk):
        # …
        pass

    # update object
    def patch(self, request, pk):
        # …
        pass

    # delete object
    def delete(self, request, pk):
        # …
        pass


class MyCreateCategoryView(View):
    # create object
    def post(self, request):
        # …
        pass

But regardless, Django is not designed to make (CRUD) APIs. What you can use to make such APIs is a ModelViewSet (or ViewSet) from the Django REST framework [drf-doc]. This also provides serializers that normally make the mapping between the request data and a model object, and from a model object to response data easier, and works with a router that thus then can route the items properly.

Таким образом, мы можем реализовать это следующим образом:

class MyCategoryViewSet(viewsets.ViewSet):
    # GET /categories/
    def list(self, request):
        # …
        pass

    # POST /categories/
    def create(self, request):
        # …
        pass

    # GET /categories/1/
    def retrieve(self, request, pk=None):
        # …
        pass

    # PUT /categories/1/
    def update(self, request, pk=None):
        # …
        pass

    # PATCH /categories/1/
    def partial_update(self, request, pk=None):
        # …
        pass

    # DELETE /categories/1/
    def destroy(self, request, pk=None):
        # …
        pass

Пути не определяются ViewSet, однако комментарий в верхней части каждого мехтода - это то, как SimpleRouter [drf-doc] будет это делать. Таким образом, вы регистрируете ViewSet с помощью:

from rest_framework import routers

router = routers.SimpleRouter()
router.register('categories', MyCategoryViewSet)
urlpatterns = router.urls
Вернуться на верх