django prefetch_related & 预取嵌套
django prefetch_related & Prefetch nested
我正在尝试 return,对于每个 UserProfile
,它具有一对多 Subscription
,它具有 Artist
和 UserProfile
,每个艺术家有很多 ReleaseGroup
,每个 UserProfile
有 count 个 future 发行组.
简而言之:我想 return 每个用户拥有的所有订阅的即将发布的总数。
但是我还没来得及数数就卡住了...
context['test_totals'] = UserProfile.objects.prefetch_related(
Prefetch('subscription_set', queryset=Subscription.objects.
prefetch_related(Prefetch('artist', queryset=Artist.objects.
prefetch_related(Prefetch('release_groups',
queryset=ReleaseGroup.objects.filter(
release_date__gte=startdate
), to_attr='rggg')), to_attr='arti')), to_attr='arts'))
正在访问 userprofile.arts|length
模板中的 return 订阅总数,但 rggg
和 arti
return 什么都没有。如何做到这一点?
我尝试使用 filter(profile='userprofile
)` 对自身进行过滤,但 return 是一个错误。如果我可以对自己进行过滤,我可能会让它起作用吗?
context['test_totals'] = UserProfile.objects.prefetch_related(
Prefetch(
'subscription_set',
queryset=Subscription.objects.select_related(
'artist', 'profile').prefetch_related(
Prefetch(
'artist__release_groups',
queryset=ReleaseGroup.objects.filter(
release_date__gte=startdate
),
to_attr='release_groups'
)
),
to_attr='subscriptions'
)
)
我还没有机会对此进行测试,但它应该可以工作。您在不支持的外键 artist
上使用 prefetch_related; prefetch_related 用于支持项目列表的关系。因此,您预取 subscription_set 并对艺术家使用 select_related,然后预取 artist__release_groups
关系。现在你应该有 profile_instance.subscriptions
...subscriptions[index].artist
...subscriptions[index].artist.release_groups
*编辑:
在与 OP 讨论后,我们想使用这种方法,但没有使用 Date 过滤器。
UserProfile.objects.annotate(
rgs=Count(
'subscription_set__artist__release_groups',
filter=Q(subscription_set__artist__release_groups__release_date__gte=startdate),
distinct=True
)
)
真正的答案是使用 django.db.models
Case
和 When
作为 OP,我发现了。查看他对已完成查询的回答
在 Nicholas Cluade LeBlanc 的大量帮助下,下面是工作查询:
UserProfile.objects.annotate(rgs=Count(
Case(
When(subscriptions__artist__release_groups__release_date__gte=startdate, then=F('subscriptions__artist__release_groups__release_date')),
When(subscriptions__artist__release_groups__release_date__lt=startdate, then=None),
output_field=DateField()
)
))
正如 Nicholas 所建议的,subscriptions
是 profile
related_query_name
集 Subscription
。
我正在尝试 return,对于每个 UserProfile
,它具有一对多 Subscription
,它具有 Artist
和 UserProfile
,每个艺术家有很多 ReleaseGroup
,每个 UserProfile
有 count 个 future 发行组.
简而言之:我想 return 每个用户拥有的所有订阅的即将发布的总数。
但是我还没来得及数数就卡住了...
context['test_totals'] = UserProfile.objects.prefetch_related(
Prefetch('subscription_set', queryset=Subscription.objects.
prefetch_related(Prefetch('artist', queryset=Artist.objects.
prefetch_related(Prefetch('release_groups',
queryset=ReleaseGroup.objects.filter(
release_date__gte=startdate
), to_attr='rggg')), to_attr='arti')), to_attr='arts'))
正在访问 userprofile.arts|length
模板中的 return 订阅总数,但 rggg
和 arti
return 什么都没有。如何做到这一点?
我尝试使用 filter(profile='userprofile
)` 对自身进行过滤,但 return 是一个错误。如果我可以对自己进行过滤,我可能会让它起作用吗?
context['test_totals'] = UserProfile.objects.prefetch_related(
Prefetch(
'subscription_set',
queryset=Subscription.objects.select_related(
'artist', 'profile').prefetch_related(
Prefetch(
'artist__release_groups',
queryset=ReleaseGroup.objects.filter(
release_date__gte=startdate
),
to_attr='release_groups'
)
),
to_attr='subscriptions'
)
)
我还没有机会对此进行测试,但它应该可以工作。您在不支持的外键 artist
上使用 prefetch_related; prefetch_related 用于支持项目列表的关系。因此,您预取 subscription_set 并对艺术家使用 select_related,然后预取 artist__release_groups
关系。现在你应该有 profile_instance.subscriptions
...subscriptions[index].artist
...subscriptions[index].artist.release_groups
*编辑:
在与 OP 讨论后,我们想使用这种方法,但没有使用 Date 过滤器。
UserProfile.objects.annotate(
rgs=Count(
'subscription_set__artist__release_groups',
filter=Q(subscription_set__artist__release_groups__release_date__gte=startdate),
distinct=True
)
)
真正的答案是使用 django.db.models
Case
和 When
作为 OP,我发现了。查看他对已完成查询的回答
在 Nicholas Cluade LeBlanc 的大量帮助下,下面是工作查询:
UserProfile.objects.annotate(rgs=Count(
Case(
When(subscriptions__artist__release_groups__release_date__gte=startdate, then=F('subscriptions__artist__release_groups__release_date')),
When(subscriptions__artist__release_groups__release_date__lt=startdate, then=None),
output_field=DateField()
)
))
正如 Nicholas 所建议的,subscriptions
是 profile
related_query_name
集 Subscription
。