gpt4 book ai didi

Django Rest Framework - 创建作为嵌套对象的列表属性传递的对象

转载 作者:行者123 更新时间:2023-12-04 12:07:39 24 4
gpt4 key购买 nike

撇开 Xzibit 开玩笑,这是我的模型:

from django.db import models

class ProjectProfitAndLoss(models.Model):
pass

class Component(models.Model):
profit_and_loss = models.ForeignKey(ProjectProfitAndLoss, related_name='components')
name = models.CharField(max_length=250)

class ComponentProductionVolume(models.Model):
component = models.ForeignKey(Component, related_name='volumes')
offset = models.IntegerField()
volume = models.DecimalField(max_digits=16, decimal_places=4)

序列化器:
from rest_framework import serializers

class ComponentProductionVolumeSerializer(serializers.ModelSerializer):
class Meta:
model = ComponentProductionVolume


class ComponentSerializer(serializers.ModelSerializer):
volumes = ComponentProductionVolumeSerializer(many=True, allow_add_remove=True)

class Meta:
model = Component


class ProjectProfitAndLossSerializer(serializers.ModelSerializer):
components = ComponentSerializer(many=True, allow_add_remove=True)

class Meta:
model = ProjectProfitAndLoss

我想要做的是将要创建的组件连同它们的 ComponentProductionVolumes 一起发布为列表 - 也作为列表。所以我的 json 看起来像这样:
[
{
"name": "component 1",
"profit_and_loss": 3,
"volumes": [
{
"offset": 0,
"volume": 2
},
{
"offset": 1,
"volume": 3
},
{
"offset": 2,
"volume": 2
},
]
},
{
"name": "component 2"
"profit_and_loss": 3,
"volumes": [
{
"offset": 0,
"volume": 4
},
{
"offset": 1,
"volume": 2
},
{
"offset": 2,
"volume": 5
},
]
}
]

不幸的是,我得到的是一个验证错误:
components: [{volumes:[{component:[This field is required.]},{volumes:[{component:[This field is required.]} ... /* error repeated for each volume sent */ ]}] 

如果我理解正确,此错误会告诉我在发送的每个卷中都包含组件 ID。但由于我希望 DRF 与它们的体积一起创建组件,这是不可能的,因为组件尚不存在。

让 DRF 创建组件,然后是 ComponentProductionVolumes 的最佳方法是什么?

最佳答案

DRF 当前(版本 2.3.13)没有创建嵌套关系的内置功能。但是,通过覆盖 create 来实现这一点非常简单。在 ListCreateView :

class ComponentList(generics.ListCreateAPIView):
model = Component
serializer_class = ComponentSerializer

def create(self, request, *args, **kwargs):
data = request.DATA

# note transaction.atomic was introduced in Django 1.6
with transaction.atomic():
component = Component(
profit_and_loss=data['component_comments'],
name=data['name']
)
component.clean()
component.save()

for volume in data['volumes']:
ComponentProductionVolume.objects.create(
component=component,
offset=volume['offset'],
volume=volume['volume']
)

serializer = ComponentSerializer(component)
headers = self.get_success_headers(serializer.data)

return Response(serializer.data, status=status.HTTP_201_CREATED,
headers=headers)

笔记

以上代码使用 transaction.atomic这是在 Django 1.6 中引入的。在这种情况下它会派上用场,因为如果出现问题,它会回滚更改。有关更多信息,请参阅有关事务的 Django 文档:

https://docs.djangoproject.com/en/dev/topics/db/transactions/

此外,此示例创建了一个 Component实例,但可以通过修改客户端一次发送一个组件 POST 请求或修改上述代码来创建多个实例。

希望这可以帮助!

关于Django Rest Framework - 创建作为嵌套对象的列表属性传递的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23153040/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com