python - 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
- 如果数据类型是 OrderedDict,我不知道如何提取或访问数据。我该怎么做呢?
我想为 Selling 和 SellingProduct、Painting 创建一条记录,我不想在每个请求中创建 Customer、Address、Product 记录,我将使用存在(在前端选择的)数据。
提前感谢大家的帮助!
解决方案
如果您进行一些修改,您的第一种方法应该有效。您的销售模型依赖于客户,因此您首先需要创建一个客户。然后,您的 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
推荐阅读
- json - 在闭包中引用属性“_evolutionURL”需要明确的“自我”。使捕获语义明确
- vba - 无法使用 Excel VBA Selenium 登录
- spring - 使用 RedisTemplate 将不同的对象作为字符串迭代
- html - 我怎样才能延迟打字稿?
- laravel - Laravel如何在模型关系中获取id参数?
- javascript - 无法返回 JavaScript 嵌套回调函数内部函数返回值
- android - 当应用程序被杀死时,无头任务会自行杀死
- c++ - 我们如何在没有 stoi 命令的情况下将字符串转换为整数 / 以输入日期和输出整数
- php - PHP 图像无法正确显示
- java - 同步线程池ExecutorService