代码之家  ›  专栏  ›  技术社区  ›  zerohedge

django预取相关&预取嵌套

  •  1
  • zerohedge  · 技术社区  · 6 年前

    我想回来,每一个人 UserProfile ,其中有一对多 Subscription ,两个都有外键 Artist 小精灵 ,每个艺术家都有许多 ReleaseGroup , the 计数 属于 未来 释放每个 小精灵 有。

    简而言之:我想返回每个用户拥有的所有订阅的即将发布版本的总数。

    不过,在我数数之前,我被卡住了…

        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 in template返回订阅的总数,但是 rggg arti 不返回任何内容。怎么能做到?

    我试着对self进行过滤,比如说, filter(profile='userprofile )`但这会返回一个错误。如果我能过滤掉自我,我就能让它工作了?

    2 回复  |  直到 6 年前
        1
  •  2
  •   zerohedge    6 年前

    在尼古拉斯·克鲁德·勒布朗的大量帮助下,下面是一个有效的查询:

    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()
                )
                ))
    

    正如尼古拉斯建议的那样, subscriptions profile related_query_name 开始 Subscription 是的。

        2
  •  2
  •   Nicholas Claude LeBlanc    6 年前
    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'
            )
        )
    

    我还没有机会测试这个,但应该可以。你在外键上使用了prefetch_related artist 不支持;prefetch_related用于关系以支持项列表。因此,您可以预取订阅集并使用与艺术家相关的select,然后预取 artist__release_groups 关系。现在你应该 profile_instance.subscriptions ...subscriptions[index].artist ...subscriptions[index].artist.release_groups

    *编辑:

    在与op讨论之后,我们想使用这个方法,但是没有使用日期过滤器。

    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 就像我和医生发现的那样。查看他对已完成查询的回答