Python Django Rest框架|可写多嵌套关系

Python Django Rest框架|可写多嵌套关系,python,django,django-rest-framework,Python,Django,Django Rest Framework,我有一些模型,它们相互嵌套。我想批量创建两个序列化程序,它们都与其他模型有关系。我查看了上的文档,但无法在代码中实现它 我发送json数据的方式如下: { 'status':true, 'products':[ { 'painting':{'amount':10}, 'product':{'id':12, } }, {

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

我发送json数据的方式如下:

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

}

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
#models.py
类地址():
...
类Customer():
地址=型号。外键(地址,…)
类绘画():
...
类产品():
...
课堂销售():
客户=型号。外键(客户,…)
products=型号.ManyToManyField(产品,通过='SellingProduct')
类SellingProduct():
销售=型号。外键(销售,…)
产品=型号。外键(产品,…)
绘画=模型。外键(绘画,…)
这是我的
序列化程序.py

class AddressSerializer():
...
类CustomerSerializer():
address=AddressSerializer()
...
类PaintingSerializer():
...
类ProductSerializer():
...
类SellingProductSerializer():
绘制=绘制序列化程序()
product=ProductSerializer()
类SellingSerializer():
customer=CustomerSerializer()
products=SellingProductSerializer(many=True)
...
def创建(自我验证的_数据):
...
如果我这样写:

class SellingSerializer():
...
def创建(自我验证的_数据):
customer\u data=已验证的\u data.pop('customer')
products\u data=已验证的\u data.pop('products')
销售=销售.objects.create(**已验证的_数据)#我没有在这里传递给客户
对于产品数据中的产品数据:
SellingProducts.objects.create(销售=销售,**产品数据)
退货销售
我得到了这个错误:

django.db.utils.IntegrityError:(1048,“列'customer\u id'不能为空”)
如果我这样写:

class SellingSerializer():
...
def创建(自我验证的_数据):
销售=销售.objects.create(**已验证的_数据)#我没有在这里传递给客户
退货销售
我得到了这个错误:

ValueError:无法分配“OrderedDict…”。。。
…Selling.customer必须是“customer”实例
  • 如果数据类型为OrderedICT,我不知道如何提取或访问数据。我如何才能做到这一点
我想为销售和销售产品、绘画创建一个记录,我不想在每个请求中创建客户、地址、产品记录,我将使用现有(前端选定)数据。
提前感谢您的帮助!

如果您做了一些修改,您的第一种方法应该会奏效。您的销售模式取决于客户,因此您首先需要创建客户。然后,您的SellingProduct模型取决于产品和绘画,因此您首先需要创建产品和绘画,然后创建销售模式具有以下实例的产品:

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

}

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
当然,这种方法会为每个请求创建新的客户、产品和绘画。这真的是您想要的吗?如果您不想为每个请求创建新的产品和绘画实例,而是使用对现有实例的引用,您可以在SellingSerializer和Sell中将它们定义为PrimaryKeyRelatedField字段lingProductSerializer。然后,您可以将创建函数更改为:

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

您需要使用
CustomerSerializer
创建客户对象和数据库行,然后才能创建带有外键的
Selling
对象。您正在尝试不传递任何内容或传递JSON(这会在错误消息中变成
OrderedDict

也许重读一下关于这个问题的文章

  • SellingSerializer与CustomerSerializerh、ProductSerializer相关

  • 在创建销售对象之前,我们可以验证每个序列化程序并创建

  • 更新验证数据

  • 这个过程是多对多的

  • 您不会只是创建客户对象产品对象。数据必须经过验证,并且可以使用CustomerSerializer和ProductSerializer。在创建它们之前,请使用CustomerSerializer和ProductSerializer序列化数据,这样创建对象才是有效的,否则会引发异常

    class SellingSerializer():
    ...
    def创建(自我验证的_数据):
    #首先,让我们来处理客户数据
    customer\u data=已验证的\u data.pop('customer')
    customer\u serializer=CustomerSerializer(数据=customer\u数据)
    customer\u serializer.is\u有效(raise\u exception=True)
    customer=customer\u serializer.save()
    已验证的_数据。更新({'customer':customer})##使用客户实例更新已验证的数据
    #创建销售对象
    selling=selling.objects.create(**validated#data)#也将收到客户实例
    #处理产品相关数据
    products\u data=已验证的\u data.pop('products')
    对于产品数据中的产品数据:
    product\u serializer=ProductSerializer(数据=product\u数据)
    product_序列化程序。是否有效(raise_exception=True)
    product=product\u序列化程序.save()
    SellingProducts.objects.create(销售=销售,产品=产品)
    退货销售
    
    也许看看,您能更具体地描述您遇到的问题吗?您应该能够按照DRF的要求,在create()中解包值并直接持久化实例docs@MatthewHegarty我编辑了它。