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

如何解决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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:40:26