Django 查询集。如何只预取唯一的?
Posted
技术标签:
【中文标题】Django 查询集。如何只预取唯一的?【英文标题】:Django querysets. How to prefetch only unique? 【发布时间】:2021-09-16 09:49:47 【问题描述】:型号:
class House(Model)
class Flat(Model):
house = ForeignKey(House, related_name="houses")
owner = ForeignKey(User)
class User(Model)
查询集:
queryset = User.objects.prefetch_related(
Prefetch("flats", queryset=Flat.objects.select_related("houses"))
然后是公寓:
% for flat in user.flats.all %
<p>№ flat.number , flat.house.name </p>
% endfor %
没关系。但是对于房子我只需要独特的
% for flat in user.flats.all %
<p>House flat.house.name </p>
% endfor %
但是这个模板给了我所有的房子,有重复的。 我怎样才能避免重复,有什么想法吗?我尝试了 .distinct() 但它不起作用,看起来我使用 distinct() 错误等。
【问题讨论】:
【参考方案1】:仅找到带有模板过滤器的解决方案。 查询集:
queryset = User.objects.filter(status="ACTIVE").prefetch_related(
Prefetch("flats", queryset=Flat.objects.select_related("house"))
)
有了这个,我可以为每个用户获得所有公寓:
% for user in object_list %
% for flat in user.flats.all %
flat.number , flat.house.name
% endfor %
% endfor %
我正在使用模板过滤器来获得独特的房子。
% for user in object_list %
% for flat in user.flats.all|get_unique_houses %
flat.house.name
% endfor %
% endfor %
# extra_tags.py
@register.filter(name="get_unique_houses")
def get_unique_houses(value):
return value.distinct('house')
【讨论】:
【参考方案2】:如果用户是多个flat
s 中的owner
,您可能最终会得到重复的房屋,这些flat
s 都在同一个house
中。要通过Flat
s 获取用户相关的所有房屋,您可以使用不同的查询,以House
开头,以便您可以使用distinct
:
distinct_houses = House.objects.filter(flats__owner=user).distinct()
上面为用户是所有者的每个公寓返回一个 House 对象,并确保您没有重复项。 (请注意,以上假设 house = ForeignKey(House, related_name="flats")
的 related_name
已更改为 flats
,因为相关名称中的“房屋”似乎是与 Flat
模型相关的拼写错误。)
或者,如果您仍然也需要通过原始queryset = User.objects.prefetch_related(...)
了解所有Flat
s 并且不想要额外的查询,您也可以在Python 中做一些内存中的操作。喜欢:
distinct_houses = flat.house for flat in user.flats.all()
旁注:基于外键字段名称为 house
,您似乎需要使用 Flat.objects.select_related('house')
而不是 Flat.objects.select_related('houses')
有错字。
【讨论】:
但问题是我需要为每个用户提供所有公寓和独特房屋的用户查询。以上是关于Django 查询集。如何只预取唯一的?的主要内容,如果未能解决你的问题,请参考以下文章
Django 1.9.5:偶尔出现反向查找字段的 FieldError
Django Rest:AssertionError:无法将唯一查询与非唯一查询组合