可写的Django Rest框架的双嵌套序列化程序



我有一个或多个product_invoice的发票,一些product_invoice可以有一个product_order(所以在ProductOrder中,productionvoiceid应该是OneToOne关系,但这对我的问题并不重要)。

我可以在2级上获得数据,但我不能创建,有这个错误:

TypeError:"orderinfo"是此函数的无效关键字参数。

但如果我在ProductInvoiceSerializer中删除orderinfo,我就可以创建Invoice和相关的Product_Invoice

我做错了什么?

django:1.9.3,DRF:3.3.3

[
{
    "invoiceid": 43,
    "stocklocationid": 1,
    "invoicecode": "OBR00040",
    "invoicedate": "2016-05-07",
    "totalamount": 500000,
    "buypricetotal": 125000,
    "discount": 0,
    "ppnamount": 50000,
    "ispaid": true,
    "deposit": 0,
    "emailaddress": "",
    "customername": "",
    "invoicenote": "",
    "isorder": false,
    "deliverydate": null,
    "products": [
        {
            "productinvoiceid": 48,
            "productid": 1,
            "quantity": 1,
            "buyingprice": 200000,
            "saleprice": 100000,
            "orderinfo": [
                {
                    "productorderid": 2,
                    "note": "",
                    "isstock": false,
                    "stocklocationid": 1,
                    "ispickedup": 0
                }
            ]
        }
    ]
},

我的型号:

class Invoice(models.Model):
    invoiceid = models.AutoField(db_column='InvoiceID', primary_key=True)
    invoicecode = models.CharField(db_column='InvoiceCode', unique=True, max_length=8)
    class Meta:
        managed = False
        db_table = 'invoice'
class ProductInvoice(models.Model):
    productinvoiceid = models.AutoField(db_column='ProductInvoiceID', primary_key=True)
    productid = models.ForeignKey(Product, models.DO_NOTHING, db_column='ProductID')
    invoiceid = models.ForeignKey(Invoice, models.DO_NOTHING, db_column='InvoiceID', related_name='products')
    quantity = models.IntegerField(db_column='Quantity', verbose_name='Quantity')
class Meta:
    managed = False
    db_table = 'product_invoice'
class ProductOrder(models.Model):
    productorderid = models.AutoField(db_column='ProductOrderID', primary_key=True)
    productinvoiceid = models.ForeignKey(ProductInvoice, models.DO_NOTHING, db_column='ProductInvoiceID', related_name='orderinfo')
    isstock = models.BooleanField(db_column='Stock', verbose_name = 'Is stock ?')
    isreadytopick = models.IntegerField(db_column='ReadyToPick')
    ispickedup = models.IntegerField(db_column='PickedUp', verbose_name = 'Already picked-up ?')
class Meta:
    managed = False
    db_table = 'product_order'

我的序列化程序:

class ProductOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = ProductOrder
        fields = ('productorderid','note','isstock','stocklocationid','ispickedup')
class ProductInvoiceSerializer(serializers.ModelSerializer):
    orderinfo = ProductOrderSerializer(many=True)
    class Meta:
        model = ProductInvoice
        fields = ('productinvoiceid', 'productid', 'quantity', 'buyingprice', 'saleprice', 'orderinfo')
    #fields = ('productinvoiceid', 'productid', 'quantity', 'buyingprice', 'saleprice')
    def create(self, validated_data):
        ordersinfo_data = validated_data.pop('orderinfo')
        product_invoice = ProductInvoice.objects.create(**validated_data)
        for orderinfo_data in ordersinfo_data:
            ProductOrder.objects.create(productinvoiceid=product_invoice, **orderinfo_data)
        return product_invoice
class InvoiceSerializer(serializers.ModelSerializer):
    products = ProductInvoiceSerializer(many=True)
    class Meta:
        model = Invoice
        fields = ('invoiceid', 'stocklocationid', 'invoicecode','invoicedate','totalamount','buypricetotal','discount','ppnamount','ispaid','deposit','emailaddress','customername','invoicenote','isorder','deliverydate','products')
    def create(self, validated_data):
        products_data = validated_data.pop('products')
        invoice = Invoice.objects.create(**validated_data)
        for product_data in products_data:
            #product_data.invoiceid = invoice.invoiceid
            ProductInvoice.objects.create(invoiceid=invoice, **product_data)
        return invoice

更新2016-05-11

view.py

@api_view(['GET', 'POST'])
def invoice_list(request):
if request.method == 'GET':
    invoices = Invoice.objects.all()
    serializer = InvoiceSerializer(invoices, many=True)
    return Response(serializer.data)
elif request.method == 'POST':
    serializer = InvoiceSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return JSONResponse(serializer.data, status=status.HTTP_201_CREATED, )
    return JSONResponse(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

由于您在ProductInvoice.objects.create(invoiceid=invoice, **product_data)ProductInvoice中手动创建ProductInvoice对象,因此模型没有任何名为orderinfo的字段。

现在既然你在使用

orderinfo = ProductOrderSerializer(many=True)

ProductInvoice需要有一个ManyToMany字段来存储orderinfo

因此,你的模型应该是这样的:

class ProductInvoice(models.Model):
    productinvoiceid = models.AutoField(db_column='ProductInvoiceID', primary_key=True)
    productid = models.ForeignKey(Product, models.DO_NOTHING, db_column='ProductID')
    invoiceid = models.ForeignKey(Invoice, models.DO_NOTHING, db_column='InvoiceID', related_name='products')
    quantity = models.IntegerField(db_column='Quantity', verbose_name='Quantity')
    orderinfo = models.ManyToManyField(ProductOrder)

您应该使用ProductInvoiceSerializer创建ProductInvoice对象:

def create(self, validated_data):
        products_data = validated_data.pop('products')
        invoice = Invoice.objects.create(**validated_data)
        for product_data in products_data:
            #product_data.invoiceid = invoice.invoiceid
            data = product_data
            data['invoiceid'] = invoice
            serializer = ProductInvoiceSerializer(data=data)
            if serializer.is_valid(raise_exception=True):
                serializer.save()
        return invoice

最新更新