我想编写一个API端点,为2个模型创建数据,通过多对多关系链接在一起。我们假设这些模型是User
和Group
。
要求:
pk
来描述它们。如果这些模型之间的关系是1-> N(即用户可以在N组中,但是一组可以与1个用户相关),那么解决方案将是微不足道的:
'user1': {'name': "robert",
'groups': [{'name': 'group1'}, {'name': 'group2'}]
}
'user2': {'name': "jean",
'groups': [{'name': 'group3'}, {'name': 'group4'}]
}
但是因为它是一个M2M,我应该如何做到这一点?嵌套不起作用:
'user1': {'name': "robert",
'groups': [{'name': 'group1'}, {'name': 'group2'}]
}
'user2': {'name': "jean",
'groups': [{'name': 'group2'}, {'name': 'group3'}]
}
在这种情况下,服务器可能会尝试创建4个组而不是3个。另外,我正在重复尝试指定两个对象两次。
请注意,这里,一个组对象是一个简单的模型,但在我的实际情况中,该对象是一个复杂的对象,具有多级嵌套,所以我不能重复自己。
你会如何解决这个问题? 我想到的唯一解决方案是进行两次HTTP调用,而不是一次。
注意:我使用的是Django和Django Rest Framework。
答案 0 :(得分:0)
假设您的用户模型中有groups = ManyToManyField(Group)
,则以下情况应该有效。
在用户序列化程序中定义字段groups = GroupSerializer()
(您必须将GroupSerializer
实现为ModelSerializer
)。
在序列化程序的create
方法中,您将拥有以下内容:
def create(self, validated_data):
// Groups list has existing groups and new ones as well
groups = validated_data.pop('groups')
// Get existing groups by name
existing_groups = Group.objects.filter(name__in=[g.name for g in groups])
existing_group_names = [g.name for g in existing_groups]
// Create new groups
groups_to_create = []
for g in groups:
if g.name not in existing_group_names:
groups_to_create.append(g)
Group.objects.bulk_create(groups_to_create)
// Now that we have all groups, create the user and add the groups to his groups list, updating the M2M relationship
user = User.objects.create_user(**validated_data)
user.groups.add(existing_groups + groups_to_create)