使用通用视图后,Django请求处理过程(以ListView为例):
在我们自定义的视图中:

class IndexView(ListView):
template_name = 'blog/index.html'
context_object_name = 'article_list' def get_context_data(self, **kwargs):
kwargs['category_list'] = Category.objects.all()
return super(IndexView, self).get_context_data() def get_queryset(self):
return Article.objects.filter(status=1)

ListView的定义:

class ListView(MultipleObjectTemplateResponseMixin, BaseListView):
"""
Render some list of objects, set by `self.model` or `self.queryset`.
`self.queryset` can actually be any iterable of items, not just a queryset.
"""

View中as_view方法:

class View(object):
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
"""
for key in initkwargs:
if key in cls.http_method_names:
raise TypeError("You tried to pass in the %s method name as a "
"keyword argument to %s(). Don't do that."
% (key, cls.__name__))
if not hasattr(cls, key):
raise TypeError("%s() received an invalid keyword %r. as_view "
"only accepts arguments that are already "
"attributes of the class." % (cls.__name__, key)) def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
self.request = request
self.args = args
self.kwargs = kwargs
return self.dispatch(request, *args, **kwargs)

dispatch方法:

def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)

dispatch方法中根据http请求的method得到handler的值(get,post...),接着调用handler方法,如果是get请求,则调用的是get方法。get方法定义在BaseListView中:

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)

get_queryset、get_context_data在父类中的定义:

class MultipleObjectMixin(ContextMixin):
"""
A mixin for views manipulating multiple objects.
"""
allow_empty = True
queryset = None
model = None
paginate_by = None
paginate_orphans = 0
context_object_name = None
paginator_class = Paginator
page_kwarg = 'page'
ordering = None def get_queryset(self):
"""
Return the list of items for this view. The return value must be an iterable and may be an instance of
`QuerySet` in which case `QuerySet` specific behavior will be enabled.
"""
if self.queryset is not None:
queryset = self.queryset
if isinstance(queryset, QuerySet):
queryset = queryset.all()
elif self.model is not None:
queryset = self.model._default_manager.all()
else:
raise ImproperlyConfigured(
"%(cls)s is missing a QuerySet. Define "
"%(cls)s.model, %(cls)s.queryset, or override "
"%(cls)s.get_queryset()." % {
'cls': self.__class__.__name__
}
)
ordering = self.get_ordering()
if ordering:
if isinstance(ordering, six.string_types):
ordering = (ordering,)
queryset = queryset.order_by(*ordering) return queryset def get_context_object_name(self, object_list):
"""
Get the name of the item to be used in the context.
"""
if self.context_object_name:
return self.context_object_name
elif hasattr(object_list, 'model'):
return '%s_list' % object_list.model._meta.model_name
else:
return None def get_context_data(self, **kwargs):
"""
Get the context for this view.
"""
queryset = kwargs.pop('object_list', self.object_list)
page_size = self.get_paginate_by(queryset)
context_object_name = self.get_context_object_name(queryset)
if page_size:
paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
context = {
'paginator': paginator,
'page_obj': page,
'is_paginated': is_paginated,
'object_list': queryset
}
else:
context = {
'paginator': None,
'page_obj': None,
'is_paginated': False,
'object_list': queryset
}
if context_object_name is not None:
context[context_object_name] = queryset
context.update(kwargs)
return super(MultipleObjectMixin, self).get_context_data(**context)

当我们自定义的视图函数IndexView中重写get_context_data时,可将需传递到template的数据赋值给kwargs变量,最终数据会加入到context上下文中:

if context_object_name is not None:
context[context_object_name] = queryset
context.update(kwargs)

最后回到BaseListView类的get方法,调用了self.render_to_response(context)进行响应输出。

Django通用视图执行过程的更多相关文章

  1. Django通用视图APIView和视图集ViewSet的介绍和使用

    原 Django通用视图APIView和视图集ViewSet的介绍和使用 2018年10月21日 14:42:14 不睡觉假扮古尔丹 阅读数:630   1.APIView DRF框架的视图的基类是 ...

  2. django通用视图

    通用视图 1. 前言 回想一下,在Django中view层起到的作用是相当于controller的角色,在view中实施的 动作,一般是取得请求参数,再从model中得到数据,再通过数据创建模板,返回 ...

  3. django通用视图之TemplateView和ListView简单介绍

    django支持类视图,与此同时django为我们提供了许多非常好用的通用视图供我们使用,这其中TemplateView.ListView和DetailView是我们经常使用到的,这里就对Templa ...

  4. django通用视图(类方法)

    这周是我入职的第一周,入职第一天看到嘉兴大佬的项目代码.视图中有类方法,我感到很困惑. 联想到之前北京融360的电话面试,问我有无写过类方法……看来有必要了解下视图的类方法,上网搜了很多,原来这就是所 ...

  5. 6:django 通用视图

    上一节我们介绍了django视图函数里面几个常用的函数,这节我们来看一下django为我们提供的一些通用视图吧 在最后面有我自己的示例代码,html部分太多了就不贴了 “简单”视图函数 正如名字所言, ...

  6. Django通用视图APIView和视图集ViewSet的介绍和使用(Django编程-1)

    1.APIView DRF框架的视图的基类是 APIView APIView的基本使用和View类似 Django默认的View请求对象是 HttpRequest,REST framework 的请求 ...

  7. Django - 通用视图

    urls.py from . import views ... url(r'^$', views.IndexView.as_view, name="index"), url(r'^ ...

  8. Django:之Sitemap站点地图、通用视图和上下文渲染器

    Django中自带了sitemap框架,用来生成xml文件 Django sitemap演示: sitemap很重要,可以用来通知搜索引擎页面的地址,页面的重要性,帮助站点得到比较好的收录. 开启si ...

  9. django系列8:优化vote页面,使用通用视图降低代码冗余

    修改detail.html,将它变为一个可用的投票页面 <h1>{{ question.question_text }}</h1> {% if error_message %} ...

随机推荐

  1. 框架基础:ajax设计方案(三)--- 集成ajax上传技术 大文件/超大文件前端切割上传,后端进行重组

    马上要过年了,哎,回家的心情也特别的激烈.有钱没钱,回家过年,家永远是舔舐伤口最好的地方.新的一年继续加油努力. 上次做了前端的ajax的上传文件技术,支持单文件,多文件上传,并对文件的格式和大小进行 ...

  2. loadrunner动态从mysql取值

    loadrunner动态从mysql取值 [需要下载跟数据库服务器一致的dll,32位或64位] loadrunner中有参数化从数据库中取值,但是只是静态的,对于一些要实时取值的数据就game ov ...

  3. C++的输入和输出

    C++是一种常用的编程语言.一个完整的程序至少要有一个输出,而我们也经常需要在程序内进行大量输入和输出.所以今天,我和大家谈一谈输入和输出. 1.cin和cout.可以连续输入,使用流(>> ...

  4. API网关Ocelot 使用Polly 处理部分失败问题

    在实现API Gateway过程中,另外一个需要考虑的问题就是部分失败.这个问题发生在分布式系统中当一个服务调用另外一个服务超时或者不可用的情况.API Gateway不应该被阻断并处于无限期等待下游 ...

  5. WPF开发进阶 - Fody/PropertyChanged(一)

    INotifyPropertyChanged 在WPF MVVM模式开发中,实现INotifyPropertyChanged的ViewModel是非常重要且常见的类: public class Mai ...

  6. css 样式重置

    html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, ...

  7. oracle_角色

    一. 每个Oracle用户都有一个名字和口令,并拥有一些由其创建的表.视图和其他资源. Oracle角色(role)就是一组权限(privilege) (或者是每个用户根据其状态和条件所需的访问类型) ...

  8. FindPkgConfig----CMake的pkg-config模块

    FindPkgConfig A pkg-config module for CMake. CMake的pkg-config模块. Finds the pkg-config executable and ...

  9. CSS 专业技巧

    使用CSS复位 CSS复位可以在不同的浏览器上保持一致的样式风格.您可以使用CSS reset 库Normalize等,也可以使用一个更简化的复位方法: * { box-sizing: border- ...

  10. 学习笔记--jQuery基础

    学习笔记也算总结知识点,有些示例可能没有具体到元素,直接给出的语法.大家有基本理解在看可能会好些. jQuery使用前提,需要安装jQuery库 jQuery 库是一个 JavaScript 文件,您 ...