问题描述
我有以下代表用户工作组的模型。每个工作组都有一个领导者和成员:
I have the following models that represent a working group of users. Each working group has a leader and members:
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对象的数组:
In DRF, I want to efficiently retrieve all groups (there are several hundred) as an array of the following json objects:
{
'id': <the_group_id>
'group_name': <the_group_name>
'leader': <id_of_leader>
'members': [<id_of_member_1>, <id_of_member_2>, ...]
}
为此,我设置了以下序列化器:
To do so, I have set up the following serializer:
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)
因此,在我看来,我可以执行以下操作:
So that in my view, I can do something like:
groups = WorkingGroup.objects.all().prefetch_related('workinggroupmember_set')
group_serializer = WorkingGroupSerializer(groups, many=True)
这可行,并给出了预期的结果,但是我发现它根本无法很好地扩展,因为预取 workinggroupmember_set
不eem可以在 get_members
方法中使用(Silky正在显示一个查询,以获取所有 WorkingGroup
对象,然后在 get_members
方法中对每个 workinggroupmember_set
调用的查询)。有没有一种方法可以在序列化程序中设置 members
字段来获取 workinggroupmember_set
的扁平/单字段版本,而无需使用 SerializerMethodField
?还是其他可以让我正确使用预取的方式?
This works, and gives the desired result, however I am finding it does not scale well at all, as the prefetching workinggroupmember_set
does not seem to be used inside of the get_members
method (Silky is showing a single query to grab all WorkingGroup
objects, and then a query for each workinggroupmember_set
call in the get_members
method). Is there a way to set up the members
field in the serializer to grab a flattened/single field version of workinggroupmember_set
without using a SerializerMethodField
? Or some other way of doing this that lets me properly use prefetch?
推荐答案
问题在这里,您正在执行全部
上的> values_list ,这会使您的 prefetch_related
无效。当前无法使用 values_list
进行预取,请参见。您可以做的是将其转换为python代码,而不是SQL
Problem here that you are doing values_list
on top of all
which nullifies your prefetch_related
. There is currently no way to do prefetch with values_list
see https://code.djangoproject.com/ticket/26565. What you can do is to transition this into python code instead of 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()]
这篇关于Django Rest Framework-有效检索反向外键上的相关字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!