我有一些模型,它们彼此嵌套。我想为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
在此先感谢大家的帮助!
答案 0 :(得分:2)
如果您进行了一些修改,您的第一种方法应该会起作用。您的销售模型取决于客户,因此您首先需要创建一个客户。然后,您的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 字段。然后,您可以将create函数更改为此:
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
答案 1 :(得分:0)
您需要使用CustomerSerializer
创建客户对象和数据库行,然后才能创建带有外键的Selling
对象。您正在尝试不传递任何内容或传递JSON(在错误消息中变成OrderedDict
)。
class SellingSerializer():
...
def create(self, validated_data):
customer_data = validated_data.pop('customer')
products_data = validated_data.pop('products')
customer = CustomerSerializer.save(**customer_data)
selling = Selling.objects.create(customer=customer, **validated_data)
for product_data in products_data:
SellingProducts.objects.create(selling=selling, **product_data)
return selling
也许在这个问题上重读了documentation。
答案 2 :(得分:0)
SellingSerializer与CustomerSerializerh,ProductSerializer相关
在创建Selling对象之前,我们可以验证每个序列化程序并创建
更新经过验证的数据
多对多过程
您将不仅仅是创建客户对象产品对象。数据必须经过验证,并且可以使用CustomerSerializer和ProductSerializer。在创建它们之前,先使用CustomerSerializer和ProductSerializer序列化数据,然后是有效的创建对象,否则引发异常。
class SellingSerializer():
...
def create(self, validated_data):
# First Let's handle Customer data
customer_data = validated_data.pop('customer')
customer_serializer = CustomerSerializer(data=customer_data)
customer_serializer.is_valid(raise_exception=True)
customer = customer_serializer.save()
validated_data.update({'customer':customer}) ## update our validated data with customer instance
# Create Selling object
selling = Selling.objects.create(**validated_data) # will receive customer instance as well
# Handle Products related Data
products_data = validated_data.pop('products')
for product_data in products_data:
product_serializer = ProductSerializer(data=product_data)
product_serializer.is_valid(raise_exception=True)
product = product_serializer.save()
SellingProducts.objects.create(selling=selling, product=product)
return selling