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 apkparameter, but these views are mapped to routes like/Menu/which don’t include apkvalue. When you send a DELETE request to this route, DRF can’t pass the requiredpkargument, 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 (
MenuDetailandMenuItemDetail), which are already correctly set up withpk-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
MenuItemoperations—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
相关产品推荐
相关产品推荐

