Django prefetch_related的Prefetch,order_by?

zer*_*dge 3 django

我想到了以下查询:

 context['user_artists'] = Artist.objects.filter(users=current_user).all()
Run Code Online (Sandbox Code Playgroud)

加上模板中的以下用法:

{% if user_artists %}
    ...
    {% for artist in user_artists %}
        ....
        <p class="small">last release: {{ artist.release_groups.last.title }}</p>
        <p class="small">date: {{ artist.release_groups.last.release_date }}</p>
Run Code Online (Sandbox Code Playgroud)

对于查询中的每个艺术家,数据库都被点击了3次。我知道可以通过.last在模板中简单保存将其降低到2 ,但这仍然不够快。

我知道我可以这样使用prefetch_related

Artist.objects.filter(users=current_user).prefetch_realted(`release_groups`).all()
Run Code Online (Sandbox Code Playgroud)

而且我还需要消除他的用法,.last因为它暗示着另一个查询。我可能可以使用模板引擎的slice方法来获取最后一个元素。但是然后我必须对相关关系进行排序:意思是,访问模板中的它们之前,需要release_group对其进行排序。这一定不能影响艺术家对象的顺序。release_date

如何才能做到这一点?

nev*_*ner 7

您可以使用Prefetch

Artist.objects.prefetch_related(Prefetch('release_groups', queryset=ReleaseGroup.objects.order_by('release_date')))
Run Code Online (Sandbox Code Playgroud)

为了避免与名称冲突,可以将其设置to_attr为其他名称:

Artist.objects.prefetch_related(Prefetch('release_groups', queryset=ReleaseGroup.objects.order_by('release_date'), to_attr='rgs')).all()
Run Code Online (Sandbox Code Playgroud)

然后,您可以访问模板中的每个缓存的发布组,如下所示:

artist.rgs.0.title

  • 是的。我想出了原因:名称冲突。我建议对您的答案进行编辑。 (2认同)