REST中的多对多字段和嵌套序列化程序:覆盖嵌套序列化程序不会';t在Django中创建嵌套对象

REST中的多对多字段和嵌套序列化程序:覆盖嵌套序列化程序不会';t在Django中创建嵌套对象,django,django-models,django-rest-framework,django-serializer,Django,Django Models,Django Rest Framework,Django Serializer,我有两个模型,具有多对多关系和 我正在尝试将嵌套数据发送到我的API。不幸的是,它只返回一个空数组 这就是我正在尝试的: 我的模型: class Building(models.Model): name = models.CharField(max_length=120, null=True, blank=True) net_leased_area = models.FloatField(null=True, blank=True) class BuildingGroup(

我有两个模型,具有多对多关系和 我正在尝试将嵌套数据发送到我的API。不幸的是,它只返回一个空数组

这就是我正在尝试的:

我的模型:


class Building(models.Model):
    name  = models.CharField(max_length=120, null=True, blank=True)
    net_leased_area = models.FloatField(null=True, blank=True)

class BuildingGroup(models.Model):
    description           = models.CharField(max_length=500, null=True, blank=True)
    buildings             = models.ManyToManyField(Building, default=None, blank=True)

我的通用API视图:

class BuildingGroupCreateAPIView(CreateAPIView):
    queryset                    = BuildingGroup.objects.all()
    serializer_class            = BuildingGroupSerializer
我的序列化程序:


class BuildingGroupSerializer(serializers.ModelSerializer):

    buildings = BuildingSerializer(many=True)

    class Meta:

        model = BuildingGroup

        fields = (
            'description',
            'buildings',
        )

    def create(self, validated_data):
        buildings_data = validated_data.pop('buildings')
        building_group = BuildingGroup.objects.create(**validated_data)
        for building_data in buildings_data:
            Building.objects.create(building_group=building_group, **building_data)
        return building_group

当我发送数据时,它会返回以下内容:


{"description":"Test Description API","buildings":[]}

在数组中,我希望有我的字典数组

当我重写create方法以发送嵌套对象时,我试图遵循这里的REST文档。()我认为我做得对,但失败了

我使用以下自定义方法发送带有请求的数据:

test_api_local(method="post", data={
        "description": "Test Description API",
        "buildings": [{'name' : 'Testname'}, .... ],
         })
非常感谢您的帮助。非常感谢

编辑:当我尝试在REST视图上测试它时,它告诉我:

TypeError:“building_group”是此函数的无效关键字参数

编辑2:以下是我的观点:

class BuildingGroupCreateAPIView(CreateAPIView):
    queryset                    = BuildingGroup.objects.all()
    serializer_class            = BuildingGroupSerializer

    def create(self, request, *args, **kwargs):
        serializer = BuildingGroupSerializer(data=self.request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

您必须显式地获取或创建
Building
实例,具体取决于负载数据中传递的id,然后将它们添加到
BuildingGroup
实例中

类NestedBuildingSerializer(serializers.ModelSerializer):
id=序列化程序.IntegerField(必需=False)
类元:
模型=建筑物
字段='\uuuu所有\uuuu'
类BuildingGroupSerializer(serializers.ModelSerializer):
建筑物=嵌套BuildingSerializer(多个=真)
类元:
模型=构建组
字段=(
“说明”,
"建筑物",,
)
def创建(自我验证的_数据):
建筑物数据=已验证的数据.pop(“建筑物”)
building\u group=BuildingGroup.objects.create(**已验证的\u数据)
buildings=[]#它将包含建筑模型实例列表
对于建筑物数据中的建筑物数据:
building\u id=building\u data.pop('id',无)
building,u=building.objects.get\u或_create(id=building\u id,
默认值=建筑(U数据)
建筑物。附加(建筑物)
#将所有传递的建筑模型实例添加到BuildingGroup实例
建筑物组。建筑物。添加(*建筑物)
返回大楼组
类BuildingGroupView(ListAPIView、CreateAPIView):
queryset=BuildingGroup.objects.all()
serializer\u class=BuildingGroupSerializer
##假设您在url.py中添加了这样的视图
URL模式=[
.....
路径('building-groups',views.BuildingGroupView.as_view(),
name='building-group'),
.....
]
在调用端点
/building groups
作为POST方法时,有效负载如下:

{
  "description": "here description",
  "buildings": [
    {
      "id": 1, # existing building of id 1
      "name": "name of building 1",
      "net_leased_area": 1800
    },
    { 
      # a new building will gets create
      "name": "name of building 2",
      "net_leased_area": 1800
    }
  ]
}
然后,它将返回如下响应:-

{
  "description": "here description",
  "buildings": [
    {
      "id": 1,
      "name": "name of building 1",
      "net_leased_area": 1800
    },
    {
      "id": 2
      "name": "name of building 2",
      "net_leased_area": 1800
    }
  ]
}
了解 以及

注意:
BuildingSerializer
NestedBuildingSerializer
都是不同的。不要把它们混在一起


任何人都不知道吗?首先,你应该在序列化程序的
create()
update()
中使用,
get\u或\u create()
进行
构建。我将我的行更改为
building\u group=BuildingGroup.objects.get\u或\u create(**validated\u data)
这会引发以下错误:
building\u data.models.multipleobjects返回:get()返回多个BuildingGroup-返回7AssertionError:`create()`没有返回对象实例。
我确实更改了这一行:
buildings.append(Building.objects.get\u或\u create(id=Building\u id,defaults={'defaults':buildings\u data[0]}))
因为它给我带来了语法错误。但也像这样,我得到了断言错误。你能再帮我一次忙吗,或者给我指出正确的方向?谢谢again@Micromegas我已经更新了答案,请再次查看。Akshay,非常感谢你的帮助和时间。太棒了!另一个问题:在我看来,这一行:
serializer=BuildingGroupSerializer(data=data)
数据指的是什么?因为我得到了一个未解析的数据引用,我不明白你在那里传递的参数是什么。这里
data
可以是你在请求中得到的有效载荷,所以你可以像
serializer=BuildingGroupSerializer(data=request.data)
啊,好的,我明白了。我仍然收到一份空的建筑清单。。。。我使用的是一个通用视图,比如:
classbuildinggroupcreateapiview(CreateAPIView)
。所以我尝试覆盖perform\u create方法,比如
def perform\u create(self,serializer):serializer=BuildingGroupSerializer(data=self.request.data)serializer.is\u valid(raise\u exception=True)serializer.save()
这就是你的意思吗?因为不幸的是,我仍然得到一张空的建筑清单