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

Django Rest Framework发票生成API中invoice.is_valid()验证失败问题求助

Fixing the invoice.is_valid() Validation Error in Your DRF Invoice API

Hey there! Let's break down why your validation is failing and fix it step by step. Looking at your code, error trace, and request data, there are a few key mismatches and missing configurations causing the issue:

1. Mismatched Serializer Field Name

Your InvoiceSerializer defines a field called item = ItemSerializer(many=True), but your request data uses items (plural), and Django's default reverse relation between Invoice and Item is also named items (since Item has a foreign key to Invoice).

DRF is looking for a required item field that doesn't exist in your request, hence the "This field is required" error.

2. Unnecessary Required invoice Field in ItemSerializer

Looking at the traceback, your ItemSerializer automatically includes the invoice foreign key field as a required PrimaryKeyRelatedField. But you don't want the frontend to send this value—you'll associate items with the invoice in your create method. This adds another layer of validation failure because the request doesn't include this field.

3. Inconsistent Key Name in create Method

Your create method tries to pop items from validated data, but before fixing the serializer field name, this key wouldn't exist (since the serializer was looking for item instead).


Fixed Serializers Code

Here's the corrected serializers.py with all these issues addressed:

from django.db.models import fields
from rest_framework import serializers
from rest_framework.fields import ReadOnlyField
from invoiceAPI.models import Seller, Buyer, Invoice, Item

class SellerSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    class Meta:
        model = Seller
        fields = '__all__'

class BuyerSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    class Meta:
        model = Buyer
        fields = '__all__'

class ItemSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(read_only=True)
    # Mark the invoice field as read-only so it's not required in the request
    invoice = serializers.PrimaryKeyRelatedField(read_only=True)
    class Meta:
        model = Item
        fields = '__all__'

class InvoiceSerializer(serializers.ModelSerializer):
    seller = SellerSerializer(many=False)
    buyer = BuyerSerializer(many=False)
    # Rename to `items` to match request data and Django's reverse relation
    items = ItemSerializer(many=True)
    class Meta:
        model = Invoice
        depth = 1
        fields = ('seller', 'buyer', 'items', 'date')
    
    def create(self, validated_data):
        seller_data = validated_data.pop('seller')
        buyer_data = validated_data.pop('buyer')
        # Now `items` matches the serializer field name
        items_data = validated_data.pop('items')
        
        seller = Seller.objects.create(**seller_data)
        buyer = Buyer.objects.create(**buyer_data)
        invoice = Invoice.objects.create(seller=seller, buyer=buyer, **validated_data)
        
        # Create each item and associate it with the new invoice
        for item_data in items_data:
            Item.objects.create(invoice=invoice, **item_data)
        
        return invoice

Bonus: Fix a Minor Bug in Invoice Model

While not related to the validation error, your invoice_number method has a type error—you're trying to concatenate a string with an integer (self.id). Update it to:

def invoice_number(self):
    id_str = str(self.id)
    if len(id_str) == 1:
        return f'Invoice00{id_str}'
    elif len(id_str) == 2:
        return f'Invoice0{id_str}'
    else:
        return f'Invoice{id_str}'

With these changes, your invoice.is_valid() should pass, and the API will correctly create the seller, buyer, invoice, and associated items from your request data.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 05:52:37