繁体   English   中英

Django CBV:在 ListView 的 get_context_data 方法中重用来自 get_queryset 的查询

[英]Django CBVs: reuse query from get_queryset in get_context_data method in ListView

我需要将标签object 传递给模板,但无需在 get_context_data 方法中对数据库进行额外查询。
您能否告诉我是否有更优雅的方式从 get_context_data 中的 get_queryset 方法获取值。 如果有更优雅的方式,在 Django 视图中声明自己的字段是否正确

class PostListView(ListView):
    model = Post
    paginate_by = 3
    context_object_name = 'posts'
    template_name = 'blog/post/list.html'

    tag = None

    def get_queryset(self):
        data = super().get_queryset()
        if tag_slug := self.kwargs.get('tag_slug'):
            self.tag = get_object_or_404(Tag, slug=tag_slug)
            data = data.filter(tags__in=[self.tag])
        return data

    def get_context_data(self, *, object_list=None, **kwargs):
        data = super().get_context_data(**kwargs)
        data['tag'] = self.tag
        return data

获取查询集应该只准备查询集,而不会对数据库产生任何影响。 在你的情况下,你做了很多不需要的事情:

 def get_queryset(self):
    query =  Q()
    if self.kwargs.get('tag_slug'):
        query = Q(tags__slug=self.kwargs['tag_slug']) 
    return super().get_queryset().filter(query).select_related('tag')

实际上,上面的 function 是 One-liner。 您不需要上下文中的任何标签,但如果您愿意:

def get_context_data(self, *args, **kwargs):
    response = super().get_context_data(*args, **kwargs)
    if len(response['object_list']) : # only one hit in database
        response['tag'] = response['object_list'][0].tag
    else:
        raise Http404
    return response

len 在数据库中询问,并获取所有对象。

根据回复,我编辑以下代码:

  • 因为我需要标签名称,它可能与 tug slug 不同,所以我重写 get 方法来获取标签 object 并且稍后不执行 uselees 代码

  • 从 get_queryset 中删除查询

  • 由于遍历我的模板中的帖子,将“object_list”替换为“posts”

     class PostListView(ListView): model = Post paginate_by = 3 context_object_name = 'posts' template_name = 'blog/post/list.html' tag = None def get(self, request, *args, **kwargs): if tag_slug:= self.kwargs.get('tag_slug'): self.tag = get_object_or_404(Tag, slug=tag_slug) return super(PostListView, self).get(request, *args, **kwargs) def get_queryset(self): query = Q() if self.tag: query = Q(tags__slug=self.tag) return super(PostListView, self).get_queryset().filter(query) def get_context_data(self, *args, **kwargs): response = super().get_context_data(*args, **kwargs) if len(response['posts']): response['tag'] = self.tag else: raise Http404 return response

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM