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?
答案 0 :(得分:3)
当前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)
上面的代码使用了Django 1.6中引入的transaction.atomic
。它在这种情况下派上用场,因为如果出现问题,它会回滚更改。有关更多信息,请参阅有关事务的Django文档:
https://docs.djangoproject.com/en/dev/topics/db/transactions/
此外,此示例创建一个Component
实例,但创建多个实例可以通过修改客户端一次发送一个Component POST请求或修改上述代码来完成。
希望这有帮助!
答案 1 :(得分:2)
更新问题背景的答案
目前在DRF 3.1中,支持此功能,您可以查看完整文档here。