带有Django Rest Framework的可写双嵌套序列化器 [英] Writable Double-nested serializers with Django Rest Framework

查看:68
本文介绍了带有Django Rest Framework的可写双嵌套序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有1个或多个 product_invoice 的发票,并且某些 product_invoice 可以具有1个 product_order (因此在ProductOrder中,productinvoiceid应该是OneToOne冲突,但这对我的问题并不重要.

I have invoice with 1 or multiple product_invoice, and some product_invoice can have 1 product_order (so in ProductOrder, productinvoiceid shoulb be a OneToOne relashionship but it is not important for my issue).

我能够获取2级数据,但是我无法创建,出现此错误:

I am able to get data on the 2 level, but I can't create, there is this error :

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

TypeError: 'orderinfo' is an invalid keyword argument for this function.

但是,如果我在 ProductInvoiceSerializer 中删除 orderinfo ,则可以创建发票和相关的 Product_Invoice .

But if I remove orderinfo in ProductInvoiceSerializer I am able to create Invoice and related Product_Invoice.

我做错了什么?

django:1.9.3,DRF:3.3.3

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

UPDATE 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 对象,位于 ProductInvoice.objects.create(invoiceid = invoice,** product_data) ProductInvoice 模型没有名为 orderinfo 的任何字段.

Since you are manually creating ProductInvoice object here at ProductInvoice.objects.create(invoiceid=invoice, **product_data) and ProductInvoice model doesn't have any field named orderinfo.

现在,因为您正在使用

orderinfo = ProductOrderSerializer(many=True)

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

ProductInvoice needs to have a ManyToMany field to store orderinfo

因此您的建模应该是这样的:

Thus you model should be like this:

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)

OR

您应该使用 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

这篇关于带有Django Rest Framework的可写双嵌套序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆