Django Rest Framework - 有效地检索反向外键的相关字段

2024-01-11

我有以下代表用户工作组的模型。每个工作组均设一名组长和成员:

class WorkingGroup(models.Model):
    group_name = models.CharField(max_length=255)
    leader = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)

class WorkingGroupMember(models.Model):
    group = models.ForeignKey(WorkingGroup, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)

在 DRF 中,我想高效地检索所有组(有数百个)作为以下 json 对象的数组:

{
    'id': <the_group_id>
    'group_name': <the_group_name>
    'leader': <id_of_leader>
    'members': [<id_of_member_1>, <id_of_member_2>, ...]
}

为此,我设置了以下序列化器:

class WorkingGroupSerializer(serializers.ModelSerializer):
    members = serializers.SerializerMethodField()
    class Meta:
        model = WorkingGroup
        fields = ('id', 'group_name', 'leader', 'members',)

    def get_members(self, obj):
        return obj.workinggroupmember_set.all().values_list('user_id', flat=True)

所以在我看来,我可以做这样的事情:

groups = WorkingGroup.objects.all().prefetch_related('workinggroupmember_set')
group_serializer = WorkingGroupSerializer(groups, many=True)

这有效,并给出了所需的结果,但是我发现它根本无法很好地扩展,因为预取workinggroupmember_set似乎没有在内部使用get_members方法(Silky 显示单个查询来获取所有WorkingGroup对象,然后对每个对象进行查询workinggroupmember_set调用get_members方法)。有没有办法设置members序列化器中的字段以获取扁平/单字段版本workinggroupmember_set不使用SerializerMethodField?或者其他一些方法可以让我正确使用预取?


你正在做的问题在这里values_list在之上all这会使你的prefetch_related。目前无法进行预取values_list see https://code.djangoproject.com/ticket/26565 https://code.djangoproject.com/ticket/26565。你能做的就是将其转换为Python代码而不是SQL

class WorkingGroupSerializer(serializers.ModelSerializer):
    members = serializers.SerializerMethodField()
    class Meta:
        model = WorkingGroup
        fields = ('id', 'group_name', 'leader', 'members',)

    def get_members(self, obj):
        return [wgm.user_id for wgm in obj.workinggroupmember_set.all()]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django Rest Framework - 有效地检索反向外键的相关字段 的相关文章

随机推荐