Python 什么时候在 Django 中使用 get、get_queryset、get_context_data?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36950416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
When to use get, get_queryset, get_context_data in Django?
提问by nastyn8
I recently learned that you should override the get method when you specifically want to do something other than what the default view does:
我最近了解到,当您特别想要执行默认视图以外的其他操作时,您应该覆盖 get 方法:
class ExampleView(generic.ListView):
template_name = 'ppm/ppm.html'
def get(self, request):
manager = request.GET.get('manager', None)
if manager:
profiles_set = EmployeeProfile.objects.filter(manager=manager)
else:
profiles_set = EmployeeProfile.objects.all()
context = {
'profiles_set': profiles_set,
'title': 'Employee Profiles'
}
That's simple enough, but when should I use get_queryset
or get_context_data
over get
? To me it seems like they basically do the same thing or am I just missing something? Can I use them together? This is a major source of confusion for me.
这很简单,但是我应该什么时候使用get_queryset
或get_context_data
over get
?对我来说,他们似乎基本上做同样的事情,还是我只是错过了什么?我可以一起使用它们吗?这对我来说是一个主要的困惑来源。
So to reiterate: In what cases would I use get over get_queryset
or get_context_data
and vise versa?
所以重申:在什么情况下我会使用克服get_queryset
或get_context_data
反之亦然?
回答by Anonymous
They indeed do different things.
他们确实做不同的事情。
get()
get()
This is a top-level method, and there's one for each HTTP verb - get()
, post()
, patch()
, etc. You would override it when you want to do something before a request is processed by the view, or after. But this is only called when a form view is loaded for the first time, not when the form is submitted. Basic example in the documentation. By default it will just render the configured template and return the HTML.
这是一个顶级方法,每个 HTTP 动词 - get()
、post()
、patch()
等都有一个方法。当您想在视图处理请求之前或之后执行某些操作时,可以覆盖它。但这仅在第一次加载表单视图时调用,而不是在提交表单时调用。文档中的基本示例。默认情况下,它只会呈现配置的模板并返回 HTML。
class MyView(TemplateView):
# ... other methods
def get(self, *args, **kwargs):
print('Processing GET request')
resp = super().get(*args, **kwargs)
print('Finished processing GET request')
return resp
get_queryset()
get_queryset()
Used by ListView
s - it determines the list of objects that you want to display. By default, it will just give you all for the model you specify. By overriding this method you can extend or completely replace this logic. Django documentation on the subject.
由ListView
s 使用 - 它确定要显示的对象列表。默认情况下,它只会为您指定的模型提供所有信息。通过覆盖此方法,您可以扩展或完全替换此逻辑。有关该主题的 Django 文档。
class FilteredAuthorView(ListView):
template_name = 'authors.html'
model = Author
def get_queryset(self):
# original qs
qs = super().get_queryset()
# filter by a variable captured from url, for example
return qs.filter(name__startswith=self.kwargs['name'])
get_context_data()
get_context_data()
This method is used to populate a dictionary to use as the template context. For example, ListView
s will populate the result from get_queryset()
as author_list
in the above example. You will probably be overriding this method most often to add things to display in your templates.
此方法用于填充字典以用作模板上下文。例如,ListView
旨意从填充结果get_queryset()
如author_list
在上面的例子。您可能最常覆盖此方法以添加要在模板中显示的内容。
def get_context_data(self, **kwargs):
data = super().get_context_data(**kwargs)
data['page_title'] = 'Authors'
return data
And then in your template, you can reference these variables.
然后在您的模板中,您可以引用这些变量。
<h1>{{ page_title }}</h1>
<ul>
{% for author in author_list %}
<li>{{ author.name }}</li>
{% endfor %}
</ul>
Now to answer your main question, the reason you have so many methods is to let you easily stick your custom logic with pin-point accuracy. It not only allows your code to be more readable and modular, but also more testable.
现在回答你的主要问题,你有这么多方法的原因是让你轻松地以精确的方式粘贴自定义逻辑。它不仅使您的代码更具可读性和模块化,而且更易于测试。
The documentationshould explain everything. If still not enough, you may find the sourceshelpful as well. You'll see how everything is implemented with mixins which are only possible because everything is compartmentalized.
文档应该解释一切。如果仍然不够,您可能会发现这些来源也很有帮助。你会看到一切都是如何用 mixin 实现的,因为一切都是分开的。
回答by fips
Let's look at the default implementation of ListView's get
method:
我们来看看ListView的get
方法的默认实现:
class BaseListView(MultipleObjectMixin, View):
"""
A base view for displaying a list of objects.
"""
def get(self, request, *args, **kwargs):
self.object_list = self.get_queryset()
allow_empty = self.get_allow_empty()
if not allow_empty:
# When pagination is enabled and object_list is a queryset,
# it's better to do a cheap query than to load the unpaginated
# queryset in memory.
if (self.get_paginate_by(self.object_list) is not None
and hasattr(self.object_list, 'exists')):
is_empty = not self.object_list.exists()
else:
is_empty = len(self.object_list) == 0
if is_empty:
raise Http404(_("Empty list and '%(class_name)s.allow_empty' is False.")
% {'class_name': self.__class__.__name__})
context = self.get_context_data()
return self.render_to_response(context)
You will notice that get_queryset
gets called in the first line. You can simply overwrite that if you just want to return your model's queryset after applying some filtering/ordering etc.
您会注意到get_queryset
在第一行中被调用。如果您只想在应用一些过滤/排序等后返回模型的查询集,您可以简单地覆盖它。
You don't need to overwrite the whole get
method for that because you will be missing on all this provided functionality i.e. pagination, 404 checks etc.
您不需要为此覆盖整个get
方法,因为您将缺少所有这些提供的功能,即分页、404 检查等。
get_context_data
merges the resulting queryset together with context data like querystring parameters for pagination etc.
get_context_data
将结果查询集与上下文数据(如用于分页的查询字符串参数等)合并在一起。
What I would recommend would be to check with django's source every once in a while and try to understand it a little bit so that you can recognize the most appropriate method you can overwrite/replace.
我建议您每隔一段时间检查一下 django 的源代码,并尝试对其进行一些了解,以便您可以识别出可以覆盖/替换的最合适的方法。