首页 > 解决方案 > Django 休息框架 | 可写多重嵌套关系

问题描述

我有一些模型,它们相互嵌套。我想为 2 个序列化程序进行批量创建,它们都与其他模型有关系。我查看了有关DRF的文档,但无法在我的代码中实现它。

我像这样发送我的json数据:

{
  'status':true,
  'products':[
              {
               'painting':{'amount':10}, 
               'product':{'id':12, }
              },
              {
               'painting':{'amount':10}, 
               'product':{'id':12, }
              }
             ],
   'customer':{ 'name':'Adnan',
                'address':{'country':'Turkey'}
              },
    'total':111

}

#models.py

class Address():
    ...
class Customer():
    address = models.ForeignKey(Address, ...)
class Painting():
    ...
class Product():
    ...
class Selling():
    customer = models.ForeignKey(Customer, ...)
    products = models.ManyToManyField(Product, through='SellingProduct')
class SellingProduct():
    selling = models.ForeignKey(Selling, ...)
    product = models.ForeignKey(Product, ...)
    painting = models.ForeignKey(Painting, ...)

这是我的serializers.py

class AddressSerializer():
    ...
class CustomerSerializer():
    address = AddressSerializer()
    ...
class PaintingSerializer():
    ...
class ProductSerializer():
    ...
class SellingProductSerializer():
    painting = PaintingSerializer()
    product = ProductSerializer()

class SellingSerializer():
    customer = CustomerSerializer()
    products = SellingProductSerializer(many=True)
    ...
    def create(self, validated_data):
        ...

如果我写这个:

class SellingSerializer():
    ...
    def create(self, validated_data):
        customer_data = validated_data.pop('customer')
        products_data = validated_data.pop('products')
        selling = Selling.objects.create(**validated_data) #i didn't pass customer here
        for product_data in products_data:
            SellingProducts.objects.create(selling=selling, **product_data)
        return selling

我收到此错误:

django.db.utils.IntegrityError: (1048, "Column 'customer_id' cannot be null")

如果我写这个:

class SellingSerializer():
    ...
    def create(self, validated_data):        
        selling = Selling.objects.create(**validated_data) #i didn't pass customer here        
        return selling

我收到此错误:

ValueError: Cannot assign "OrderedDict...
..Selling.customer must be a "Customer" instance

我想为 Selling 和 SellingProduct、Painting 创建一条记录,我不想在每个请求中创建 Customer、Address、Product 记录,我将使用存在(在前端选择的)数据。

提前感谢大家的帮助!

标签: pythondjangodjango-rest-framework

解决方案


如果您进行一些修改,您的第一种方法应该有效。您的销售模型依赖于客户,因此您首先需要创建一个客户。然后,您的 SellingProduct 模型依赖于产品和绘画,因此您首先需要创建一个产品和绘画,然后创建一个带有这些实例的 SellingProduct,如下所示:

class SellingSerializer():
    ...
    def create(self, validated_data):
        customer_data = validated_data.pop('customer')
        selling_products_data = validated_data.pop('products')

        customer = Customer.objects.create(**customer_data)
        selling = Selling.objects.create(customer=customer, **validated_data)

        for selling_product_data in selling_products_data :
            product_data = selling_product_data.pop('product')
            product = Product.objects.create(**product_data)

            painting_data = selling_product_data.pop('painting')
            painting = Painting.objects.create(**painting_data)

            SellingProducts.objects.create(selling=selling, product=product, painting=painting)

        return selling

当然,这种方法会为每个请求创建一个新的客户、产品和绘画。这真的是你想要的吗?如果您不想为每个请求创建新的 Product 和 Painting 实例,而是使用对现有实例的引用,您可以将它们定义为SellingSerializer 和 SellingProductSerializer 中的PrimaryKeyRelatedField字段。然后,您可以将您的创建功能更改为:

def create(self, validated_data):
    customer = validated_data.pop('customer')
    selling_products_data = validated_data.pop('products')

    selling = Selling.objects.create(customer=customer, **validated_data)

    for selling_product_data in selling_products_data :
        SellingProducts.objects.create(selling=selling, **selling_product_data )

    return selling

推荐阅读