我有模型BottleType和OrganisationBottleType。 我想通过OrganisationBottleType的“ is_accepted”和“ points”字段注释BottleType查询集。
OrganisationBottleType模型:
PopupMenuButton( color: Colors.red, ...)
假设我具有organization_id和BottleType查询集,因此对于查询集中的每个对象,都需要找到按Bottle_type和organization过滤的OrganisationBottleType,并注释字段“ is_accepted”和“ points”。
(发现过滤后的OrganisationBottleType qs只能从中获取第一个对象,因为假设这两个字段:organization-bottle_type是唯一的)
我的想法是在注释中使用子查询,但我做不到。
我将不胜感激!
答案 0 :(得分:1)
如果我正确理解您的要求,请针对每种瓶子类型:
有两种解决问题的方法:
OrganisationBottleType
和OrganisationBottleType
对象的帮助下,获取BottleType
查询集并将.prefetch_related()
对象与python中Prefetch()
中的相应对象进行匹配BottleType
和OrganisationBottleType
的帮助下,用.annotate()
中的相应对象注释Subquery()
查询集两个选项的说明如下:
1。将.prefetch_related
与Prefetch
对象一起使用
给出:
queryset
-BottleType
查询集organisation_id
-所需组织的编号解决方案:
queryset = queryset.prefetch_related(
Prefetch(
'organisation_bottle_types',
queryset= OrganisationBottleType.objects.filter(organisation_id=organisation_id)
)
)
之后,您可以通过以下方式检索所需的数据:
for bottle_type in queryset:
if bottle_type.organisation_bottle_types.all():
related_object = bottle_type.organisation_bottle_types.all()[0]
is_accepted = related_object.is_accepted
points = related_object.points
else:
is_accepted = False
points = None
2。使用SubQuery
给出:
queryset
-BottleType
查询集organisation_id
-所需组织的编号解决方案:
organisation_bottle_types = OrganisationBottleType.objects.filter(organisation_id=organisation_id, bottle_type=OuterRef('id'))
queryset = queryset.annotate(
is_accepted=Subquery(organisation_bottle_types.values('is_accepted')[:1])
).annotate(
points=Subquery(organisation_bottle_types.values('points')[:1], output_field=BooleanField())
)
您可以这样做之后:
for bottle_type in queryset:
is_accepted = bottle_type.is_accepted
points = bottle_type.points
恢复:
就个人而言,我会选择第二种选择,因为它将在数据库级别而不是代码级别执行所有匹配的逻辑。
当您需要匹配整个对象而不仅仅是几个字段(例如问题中的points
和is_accepted
)时,第一种选择更好: