如何解决Django REST Framework的"Method \"POST\" not allowed"错误?
问题分析与修复方案
1. 路由注册错误
使用routers.SimpleRouter注册ModelViewSet时,路径只需填资源前缀(比如"wallet"),而非"wallet/create"。ModelViewSet会自动生成标准REST路由:
- POST请求对应
/api/wallet/(创建资源) - GET请求对应
/api/wallet/(列表)或/api/wallet/<pk>/(详情)
手动在路径中添加/create会导致路由匹配异常,POST方法无法被识别。
2. Serializer不应包含视图逻辑
你把post方法写在了HDWalletSerializer里,这是错误的。Serializer仅负责数据的序列化/反序列化,创建钱包这类业务逻辑应该放在视图中实现。
3. ModelViewSet缺少queryset
ModelViewSet必须指定queryset,否则无法正确生成路由、执行权限验证等核心操作。
4. 创建HDWallet对象的方式错误
HDWallet.objects.create()需要传入关键字参数,而非字典user字段应传入User实例,而非user.id
5. 请求数据获取错误
视图中获取POST请求数据应使用request.data,而非直接通过request["username"]访问。
修改后的代码
1. URL配置修改
# 创建路由实例 router = routers.SimpleRouter() # 仅注册资源前缀,由router自动生成对应路由 router.register("wallet", HDWalletCreateView, basename="wallet") urlpatterns = [ path("admin/", admin.site.urls), path("api/", include(router.urls)), ]
现在POST请求的正确地址为/api/wallet/
2. HDWalletSerializer修改(移除post方法)
from rest_framework.serializers import ModelSerializer from .models import HDWallet class HDWalletSerializer(ModelSerializer): class Meta: model = HDWallet fields = "__all__"
3. HDWalletCreateView修改(实现create方法)
from rest_framework.viewsets import ModelViewSet from rest_framework.response import Response from rest_framework import status from django.contrib.auth.models import User from django.http import Http404 from .models import HDWallet from .serializers import HDWalletSerializer from .permissions import IsUser, IsUserAuthenticated, IsAdminAuthenticated # 确保权限类已正确实现 class HDWalletCreateView(ModelViewSet): serializer_class = HDWalletSerializer permission_classes = [IsUser, IsUserAuthenticated, IsAdminAuthenticated] # 必须指定queryset queryset = HDWallet.objects.all() def create(self, request, *args, **kwargs): # 从请求体中获取用户名 username = request.data.get("username") if not username: return Response({"error": "username is required"}, status=status.HTTP_400_BAD_REQUEST) try: user = User.objects.get(username=username) except User.DoesNotExist: return Response({"error": "user does not exist"}, status=status.HTTP_404_NOT_FOUND) name = f"{user.username}_{user.id}" # 假设Wallet是你定义的HD钱包生成类,确保其方法可正常工作 wallet = Wallet.create(name) # 创建HDWallet对象,使用关键字参数 hdwallet = HDWallet.objects.create( name=name, private_key=wallet.get_key(), address=wallet.get_key().address, user=user ) # 通过序列化器返回规范数据 serializer = self.get_serializer(hdwallet) return Response( { "status": status.HTTP_201_CREATED, "message": "wallet has been successfully created!", "data": serializer.data }, status=status.HTTP_201_CREATED )
4. 额外注意事项
- 确保
Wallet类的create方法和get_key()方法能正确生成私钥与地址 - 权限类
IsUser、IsUserAuthenticated、IsAdminAuthenticated需正确实现,否则可能导致权限验证失败 - 在Postman中发送POST请求到
http://your-domain/api/wallet/,请求体携带username参数(例如JSON格式:{"username": "testuser"})
内容的提问来源于stack exchange,提问作者kaito shi
相关产品推荐
相关产品推荐

