[英]Django CBVs: reuse query from get_queryset in get_context_data method in ListView
I need to pass a Tag object to the template, but without an additional query to the database in get_context_data method.我需要将标签object 传递给模板,但无需在 get_context_data 方法中对数据库进行额外查询。
Can you please tell me if there is a more elegant way to get the value from the get_queryset method in the get_context_data.您能否告诉我是否有更优雅的方式从 get_context_data 中的 get_queryset 方法获取值。 And if there is a more elegant way, is it correct to declare your own fields in Django views
如果有更优雅的方式,在 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
get queryset should only prepare queryset without any hit in database.获取查询集应该只准备查询集,而不会对数据库产生任何影响。 In your case you do many not needed things:
在你的情况下,你做了很多不需要的事情:
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')
in reality function above is One-liner.实际上,上面的 function 是 One-liner。 You don't need any tag in context, but if you want:
您不需要上下文中的任何标签,但如果您愿意:
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 made ask in database, and get all objects. len 在数据库中询问,并获取所有对象。
Based on reply I edit my code for the following:根据回复,我编辑以下代码:
because I need tag name and it can be different from tug slug I override get method to get tag object and not execute uselees code later因为我需要标签名称,它可能与 tug slug 不同,所以我重写 get 方法来获取标签 object 并且稍后不执行 uselees 代码
removed query from get_queryset从 get_queryset 中删除查询
replaced "object_list" with "posts" due to iterating through posts in my template由于遍历我的模板中的帖子,将“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.