[英]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.