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

标签 python django performance orm django-rest-framework

我有以下代表用户工作组的模型。每个工作组都有一个领导者和成员:

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 ?或者其他一些可以让我正确使用预取的方法?

最佳答案

这里的问题是您在 all 之上执行 values_list,这会使您的 prefetch_related 无效。当前无法使用 values_list 进行预取,请参阅 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()]

关于python - Django Rest Framework-有效地检索反向外键的相关字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53092570/

相关文章:

python - 如何按频率对行进行分组?

python - 如何按索引从列表中删除元素

python - 将字符串的 Pandas DataFrame 转换为直方图

python - 使用Python将数字转换成对应的字母

django - 构建已完成,但查看文档链接已损坏

performance - Mongodb 与 Couch Db Select 性能

sql-server - 动态查询优化

python - Django 查询查找模型实例,其中 somefilefield == None?

python - 扩展 Django 用户模型并访问它

iphone - 使用 CoreData 与内存中的内存占用优势不明显/不明显 - 意见?