Как эффективно использовать HTTP-методы PUT и DELETE в Django Class-Based Views?
Я создаю CRUD-систему на Django, используя Class-Based Views. В настоящее время я пытаюсь понять, как обрабатывать HTTP PUT и DELETE запросы в моем приложении. Несмотря на обширный поиск в документации Django, мне трудно найти конкретные примеры и четкие объяснения того, как отправлять эти типы запросов в представление, основанное на классах.
Я создал класс представления CategoryView, расширяющийся из: django.views.View
, в котором успешно реализовал методы get и post. И я хочу построить свои урлы следующим образом:
- Новая категория: 127.0.0.1:8000/backendapp/categories/create .
- Список всех категорий: 127.0.0.1:8000/backendapp/categories/
- Получить только одну категорию: 127.0.0.1:8000/backendapp/categories/1
- И т.д...
Однако, когда я пытаюсь реализовать методы 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