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

DRF API创建订单时HTTP 400错误排查求助

解决DRF创建订单时的400错误问题

看起来你的问题主要出在请求数据结构不匹配、Serializer配置错误以及视图层的create逻辑不正确这几个地方,我帮你一步步拆解修复:

1. 修复React请求的数据结构问题

你现在的请求把订单数据包裹在了orderReq对象里,导致DRF的Serializer无法直接读取到total_price和puppies字段。修改React的createOrder函数,直接发送orderReq而不是包裹它:

async function createOrder(order) {
    order = order.map(element => ({'puppy' : element.puppy.id, 'amount': element.amount}))
    let orderReq = {"total_price": "500.00", "puppies": order}
    console.log(JSON.stringify(orderReq))
    const res = await fetch(REACT_APP_BACKEND_URL + `/shop/orders/`, {
        method: 'POST',
        headers: {
            "Content-Type": "application/json",
            // 别忘了带上Authorization Token,否则用户认证会有问题
            "Authorization": `Bearer ${yourTokenHere}`
        },
        // 这里直接传orderReq,不要包在{orderReq}里
        body: JSON.stringify(orderReq)
    })
    return res.json()
}

2. 修复OrderSerializer的配置错误

你的Serializer存在两个关键问题:total_price被硬编码成固定值,且嵌套的PuppyOrderSerializer无法接收创建所需的puppy ID。修改serializers.py:

class PuppyOrderSerializer(serializers.ModelSerializer):
    # 把ReadOnlyField改成PrimaryKeyRelatedField,这样可以传入puppy的ID
    puppy = serializers.PrimaryKeyRelatedField(queryset=Puppy.objects.all())
    class Meta:
        model = PuppyOrder
        fields = ('puppy', 'amount')

class OrderSerializer(serializers.ModelSerializer):
    puppies = PuppyOrderSerializer(source='puppyorder_set', many=True)
    user = serializers.ReadOnlyField(source='user.username')
    # 移除硬编码的total_price,改用模型对应的字段
    total_price = serializers.DecimalField(max_digits=9, decimal_places=2)

    class Meta:
        model = Order
        fields = ('id', 'total_price', 'puppies', 'date', 'user')
    
    # 重写create方法,处理嵌套的PuppyOrder数据
    def create(self, validated_data):
        # 取出嵌套的puppies数据,从validated_data中移除
        puppies_data = validated_data.pop('puppyorder_set')
        # 创建Order实例,传入当前用户
        order = Order.objects.create(user=self.context['request'].user, **validated_data)
        # 遍历puppies数据,创建对应的PuppyOrder关联
        for puppy_data in puppies_data:
            PuppyOrder.objects.create(order=order, **puppy_data)
        return order

3. 修复OrderList视图的perform_create逻辑

你的视图层逻辑有错误,比如拼写错误self.reqest.user,且手动调用serializer.create的方式不对。ListCreateAPIView已经帮你处理了is_valid流程,你只需要把用户信息传入validated_data即可:

class OrderList(generics.ListCreateAPIView):
    queryset = Order.objects.all()
    permission_classes = (permissions.AllowAny,)
    serializer_class = OrderSerializer

    def get_queryset(self):
        if self.request.user is None or self.request.user.is_anonymous:
            self.request.user = get_request_user_and_validate_token(self)
        return Order.objects.filter(user=self.request.user)
    
    def perform_create(self, serializer):
        # 这里不需要手动调用is_valid,视图已经处理过了
        if self.request.user.is_anonymous:
            self.request.user = get_request_user_and_validate_token(self)
        # 把用户传入serializer的save方法,而不是直接调用create
        serializer.save(user=self.request.user)

另外注意get_request_user_and_validate_token里的拼写错误:self.reqest.user应该改成self.request.user。

4. 验证请求数据

现在你的请求体应该是这样的(和你控制台输出的一致,没有外层包裹):

{"total_price":"500.00","puppies":[{"puppy":2,"amount":3},{"puppy":4,"amount":4}]}

这样修改后,DRF就能正确识别total_price和puppies字段,并且Serializer会处理嵌套的PuppyOrder创建逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:13:22