Метод @api_view не работает, а метод post работает django rest api

Я импортировал django_restframework.decorators from api_view

@api_view(['POST'])
def post_cart(self,request):
    serializer = CartItemSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
    else:
        return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)


curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8000/api/cart-items/ -d "{\"product_name\":\"name\",\"product_price\":\"41\",\"product_quantity\":\"1\"}"

Когда я использую @api_view(['GET']), я получаю эту ошибку

{
    "detail": "Method \"POST\" not allowed."
}
  

Но когда я меняю вот так, то все работает

def post(self,request):
    serializer = CartItemSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
    else:
        return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)



curl -X POST -H "Content-Type: application/json" http://127.0.0.1:8000/api/cart-items/ -d "{\"product_name\":\"name\",\"product_price\":\"41\",\"product_quantity\":\"1\"}"

Возвращается успех 200

{
    "status": "success",
    "data": {
        "id": 5,
        "product_name": "item",
        "product_price": 12.5,
        "product_quantity": 5
    }
}

Код CartItemView

from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializers import CartItemSerializer
from .models import CartItem
from django.shortcuts import get_object_or_404
from rest_framework.decorators import api_view

class CartItemViews(APIView):
    @api_view(['POST'])
    def post_cart(self,request):
        serializer = CartItemSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
        else:
            return Response({"status": "error", "data": serializer.errors}, status=status.HTTP_400_BAD_REQUEST)
    
    def get(self,request, id=None):
        if id:
            item = CartItem.objects.get(id=id)
            serializer = CartItemSerializer(item)
            return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)
        items = CartItem.objects.all()
        serializer = CartItemSerializer(items, many=True)
        return Response({"status": "success", "data": serializer.data}, status=status.HTTP_200_OK)

    def patch(self,request, id=None):
        if id:
            item = CartItem.objects.get(id=id)
            serializer = CartItemSerializer(item,data=request.data,partial=True)
            if serializer.is_valid():
               serializer.save()
               return Response({"status": "success", "data": serializer.data})
            else:
               return Response({"status": "error", "data": serializer.errors})

    def delete(self, request, id=None):
        item = get_object_or_404(CartItem, id=id)
        item.delete()
        return Response({"status": "success", "data": "Item Deleted"})

urls.py

from django.urls import path
from .views import CartItemViews

urlpatterns = [
    path('cart-items/',CartItemViews.as_view()),
    path('cart-items/<int:id>', CartItemViews.as_view()),
]

Вы не используете @api_view(['POST']) на члене представления, основанного на классе: декоратор @ap_view(…) [drf-doc] превращает функцию в представление, основанное на классе, поэтому теперь ваше post_cart - это класс внутри класса.

Что можно использовать для маршрутизации POST-запроса к методу, который не имеет имени post, это @action(…) [drf-doc]:

from rest_framework.decorators import action


class CartItemViews(APIView):
    @action(methods=['post'], detail=False)
    def post_cart(self, request):
        # …
        pass

При этом я не вижу причин, по которым использование def post здесь не сработает.

  1. Оригинальный выпуск:

Когда я использую @api_view(['GET']), я получаю эту ошибку: "detail": "Метод "POST" не разрешен."

При изменении значения

на @api_view(['POST']) вы разрешаете только Post-запросы. Если вы хотите использовать и Get, и Post запросы, вам следует установить значение @api_view(['GET', 'POST'])

  1. Проблема при использовании представления на основе классов:

все равно возникает ошибка [14/Mar/2024 21:03:37] "POST /api/cart-items/ HTTP/1.1" 405 41

Вам следует сделать запрос на почту /api/cart/post_cart/ или установить url_path='cart-items' and url_name='cart-items' на декораторе @action. ссылка

По умолчанию шаблон URL основан на имени метода, а имя URL представляет собой комбинацию имени ViewSet.basename и имени метода через дефис.

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