REST中的多对多字段和嵌套序列化程序:覆盖嵌套序列化程序不会';t在Django中创建嵌套对象
我有两个模型,具有多对多关系和 我正在尝试将嵌套数据发送到我的API。不幸的是,它只返回一个空数组 这就是我正在尝试的: 我的模型: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(
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-返回7你知道我该怎么解决这个问题吗?是因为我的多对多关系吗?非常感谢你Akshay!!我一定会仔细阅读这些主题。但是,您的代码给了我以下信息:AssertionError:`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()
这就是你的意思吗?因为不幸的是,我仍然得到一张空的建筑清单