You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRF中Delete与Update方法失效:缺失pk参数的TypeError问题

Fixing the delete()/update() TypeError in Django REST Framework

Let's break down why you're seeing TypeError: delete() missing 1 required positional argument: 'pk' and fix your API views step by step:

What's Causing the Error?

The core issue is in your list views (MenuList and MenuItemList):

  • You’ve defined a delete() method that expects a pk parameter, but these views are mapped to routes like /Menu/ which don’t include a pk value. When you send a DELETE request to this route, DRF can’t pass the required pk argument, hence the error.
  • List views are meant to handle collection-level operations (like fetching all items or creating a new one), not individual item updates/deletes. Those actions belong to your detail views (MenuDetail and MenuItemDetail), which are already correctly set up with pk-accepting methods.

Additionally, there’s a small bug in your detail views’ put() methods: you’re returning status.HTTP_404_BAD_REQUEST for invalid serializer data, but that status code is for "resource not found"—you should use status.HTTP_400_BAD_REQUEST for invalid input instead.

Corrected Code for views.py

Here’s the fixed version of your views:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.http import Http404
from .models import Menu, MenuItem
from .serializers import MenuSerializer, MenuItemSerializer

class MenuList(APIView):
    def get(self, request):
        menu = Menu.objects.all()
        serializer = MenuSerializer(menu, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = MenuSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    # Removed unnecessary delete() method from list view

class MenuDetail(APIView):
    """ Retrieve, update or delete a Menu instance."""
    def get_object(self,pk):
        try:
            return Menu.objects.get(pk=pk)
        except Menu.DoesNotExist:
            raise Http404
    
    def get(self, request,pk):
        menu = self.get_object(pk)
        menu = MenuSerializer(menu)
        return Response(menu.data)
    
    def put(self, request, pk):
        menu = self.get_object(pk)
        serializer = MenuSerializer(menu, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        # Fixed status code to 400 for invalid input
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        menu = self.get_object(pk)
        menu.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

class MenuItemList(APIView):
    def get(self, request):
        menuitem = MenuItem.objects.all()
        serializer = MenuItemSerializer(menuitem, many=True)
        return Response(serializer.data)
    
    def post(self, request):
        serializer = MenuItemSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    # Removed unnecessary delete() method from list view

class MenuItemDetail(APIView):
    def get_object(self,pk):
        try:
            return MenuItem.objects.get(pk=pk)
        except MenuItem.DoesNotExist:
            raise Http404
    
    def get(self, request, pk):
        menuitem = self.get_object(pk)
        menuitem = MenuItemSerializer(menuitem)
        return Response(menuitem.data)
    
    def put(self, request, pk):
        menuitem = self.get_object(pk)
        serializer = MenuItemSerializer(menuitem, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        # Fixed status code to 400 for invalid input
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    
    def delete(self, request, pk):
        menuitem = self.get_object(pk)
        menuitem.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

How to Test the Fixed API

  • Update a Menu item: Send a PUT request to http://your-domain/Menu/<pk>/ (replace <pk> with the actual ID of the menu item) with your updated data.
  • Delete a Menu item: Send a DELETE request to http://your-domain/Menu/<pk>/.
  • The same logic applies to MenuItem operations—use the /MenuItem/<pk>/ route for updates and deletes.

Your existing routes in urls.py are already correctly set up to map these detail actions, so no changes are needed there.

内容的提问来源于stack exchange,提问作者abhinavsharma1494

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:30:07