Django中由wsgi模块接管http请求,核心处理方法为get_wsgi_application,其定义如下:

def get_wsgi_application():
"""
The public interface to Django's WSGI support. Should return a WSGI
callable.
Allows us to avoid making django.core.handlers.WSGIHandler public API, in
case the internal WSGI implementation changes or moves in the future.
"""
django.setup()
return WSGIHandler()

WSGIHandler(代码有节减):

class WSGIHandler(base.BaseHandler):
initLock = Lock()
request_class = WSGIRequest def __call__(self, environ, start_response):
# Set up middleware if needed. We couldn't do this earlier, because
# settings weren't available.
if self._request_middleware is None:
with self.initLock:
try:
# Check that middleware is still uninitialized.
if self._request_middleware is None:
self.load_middleware()
except:
# Unload whatever middleware we got
self._request_middleware = None
raise set_script_prefix(get_script_name(environ))
signals.request_started.send(sender=self.__class__, environ=environ)
try:
request = self.request_class(environ)
except UnicodeDecodeError:
logger.warning('Bad Request (UnicodeDecodeError)',
exc_info=sys.exc_info(),
extra={
'status_code': 400,
}
)
response = http.HttpResponseBadRequest()
else:
response = self.get_response(request) response._handler_class = self.__class__ status = '%s %s' % (response.status_code, response.reason_phrase)
response_headers = [(str(k), str(v)) for k, v in response.items()]
for c in response.cookies.values():
response_headers.append((str('Set-Cookie'), str(c.output(header=''))))
start_response(force_str(status), response_headers)
if getattr(response, 'file_to_stream', None) is not None and environ.get('wsgi.file_wrapper'):
response = environ['wsgi.file_wrapper'](response.file_to_stream)
return response

从代码中可以看到,当WSGIHandler对象被调用的时候,首先会判断请求中间件是否为None,如果为None,则通过self.load_middleware()加载中间件。之后调用self.get_response(request)获得http响应对象。BaseHandler的load_middleware、get_response方法定义如下:

BaseHandler(代码有节减):

class BaseHandler(object):
# Changes that are always applied to a response (in this order).
response_fixes = [
http.conditional_content_removal,
] def __init__(self):
self._request_middleware = None
self._view_middleware = None
self._template_response_middleware = None
self._response_middleware = None
self._exception_middleware = None def load_middleware(self):
"""
Populate middleware lists from settings.MIDDLEWARE_CLASSES. Must be called after the environment is fixed (see __call__ in subclasses).
"""
self._view_middleware = []
self._template_response_middleware = []
self._response_middleware = []
self._exception_middleware = [] request_middleware = []
for middleware_path in settings.MIDDLEWARE_CLASSES:
mw_class = import_string(middleware_path)
try:
mw_instance = mw_class()
except MiddlewareNotUsed as exc:
if settings.DEBUG:
if six.text_type(exc):
logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc)
else:
logger.debug('MiddlewareNotUsed: %r', middleware_path)
continue if hasattr(mw_instance, 'process_request'):
request_middleware.append(mw_instance.process_request)
if hasattr(mw_instance, 'process_view'):
self._view_middleware.append(mw_instance.process_view)
if hasattr(mw_instance, 'process_template_response'):
self._template_response_middleware.insert(0, mw_instance.process_template_response)
if hasattr(mw_instance, 'process_response'):
self._response_middleware.insert(0, mw_instance.process_response)
if hasattr(mw_instance, 'process_exception'):
self._exception_middleware.insert(0, mw_instance.process_exception) # We only assign to this when initialization is complete as it is used
# as a flag for initialization being complete.
self._request_middleware = request_middleware def get_response(self, request):
"Returns an HttpResponse object for the given HttpRequest" # Setup default url resolver for this thread, this code is outside
# the try/except so we don't get a spurious "unbound local
# variable" exception in the event an exception is raised before
# resolver is set
urlconf = settings.ROOT_URLCONF
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.get_resolver(urlconf)
# Use a flag to check if the response was rendered to prevent
# multiple renderings or to force rendering if necessary.
response_is_rendered = False
try:
response = None
# Apply request middleware
for middleware_method in self._request_middleware:
response = middleware_method(request)
if response:
break if response is None:
if hasattr(request, 'urlconf'):
# Reset url resolver with a custom URLconf.
urlconf = request.urlconf
urlresolvers.set_urlconf(urlconf)
resolver = urlresolvers.get_resolver(urlconf) resolver_match = resolver.resolve(request.path_info)
callback, callback_args, callback_kwargs = resolver_match
request.resolver_match = resolver_match # Apply view middleware
for middleware_method in self._view_middleware:
response = middleware_method(request, callback, callback_args, callback_kwargs)
if response:
break if response is None:
wrapped_callback = self.make_view_atomic(callback)
try:
response = wrapped_callback(request, *callback_args, **callback_kwargs)
except Exception as e:
response = self.process_exception_by_middleware(e, request) # Complain if the view returned None (a common error).
if response is None:
if isinstance(callback, types.FunctionType): # FBV
view_name = callback.__name__
else: # CBV
view_name = callback.__class__.__name__ + '.__call__'
raise ValueError("The view %s.%s didn't return an HttpResponse object. It returned None instead."
% (callback.__module__, view_name)) # If the response supports deferred rendering, apply template
# response middleware and then render the response
if hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
# Complain if the template response middleware returned None (a common error).
if response is None:
raise ValueError(
"%s.process_template_response didn't return an "
"HttpResponse object. It returned None instead."
% (middleware_method.__self__.__class__.__name__))
try:
response = response.render()
except Exception as e:
response = self.process_exception_by_middleware(e, request) response_is_rendered = True except http.Http404 as exc:
logger.warning('Not Found: %s', request.path,
extra={
'status_code': 404,
'request': request
})
if settings.DEBUG:
response = debug.technical_404_response(request, exc)
else:
response = self.get_exception_response(request, resolver, 404, exc) try:
# Apply response middleware, regardless of the response
for middleware_method in self._response_middleware:
response = middleware_method(request, response)
# Complain if the response middleware returned None (a common error).
if response is None:
raise ValueError(
"%s.process_response didn't return an "
"HttpResponse object. It returned None instead."
% (middleware_method.__self__.__class__.__name__))
response = self.apply_response_fixes(request, response)
except: # Any exception should be gathered and handled
signals.got_request_exception.send(sender=self.__class__, request=request)
response = self.handle_uncaught_exception(request, resolver, sys.exc_info()) response._closable_objects.append(request) # If the exception handler returns a TemplateResponse that has not
# been rendered, force it to be rendered.
if not response_is_rendered and callable(getattr(response, 'render', None)):
response = response.render() return response

get_response方法中,循环遍历执行已经加载的request middleware,调用middleware将返回None 或者HttpResponse对象,如果返回前者,继续处理其它中间件,如果返回一个 HttpResponse,就处理中止。接着,应用view middleware,通过 url resolve匹配路由获取view functions(如果使用的通用视图,通过调用as_view方法,此方法为闭包,返回一个view方法)。如果middleware支持渲染(render),则应用template response中间件,然后通过调用HttpResponse对象的render方法渲染模板响应输出。

Django HTTP处理流程(自我总结)的更多相关文章

  1. django之admin流程

    admin 类复习: class Base(object): def __init__(self,val): self.val = val def func(self): self.test() pr ...

  2. Django 创建项目流程

    django 项目创建流程 1 创建项目 cmd django-admin startproject 项目名称 pycharm file -- new project -- Django -- 项目名 ...

  3. Django创建基本流程

    Django创建基本流程 1.创建工程:django-admin startproject 工程名 2.创建应用:python manage.py startapp 应用名 3.激活项目:修改sett ...

  4. django入门 -- 简单流程

    django入门 -- 简单流程 简介 通过简单示例,使用django完成基本流程的开发,学习django的主要的知识点,在后续课程中会逐个知识点进行深入讲解 以“图书-英雄”管理为示例 主要知识点介 ...

  5. 搭建Django链接MySQL流程(python2版)

    之前生成选型python3,除了用的python3的pymysql模块之外其他的都是一样的. 1.首先搭建mysql(Mariadb)数据库(单点)         安装方式分为yum安装,rpm包安 ...

  6. Django中间件执行流程

    中间件函数是 django 框架为我们预留的函数接口, 让我们可以干预请求和应答的过程 1. 获取浏览器端的IP地址: 使用 request.META[‘REMOTE_ADDR’] 2. 使用中间件 ...

  7. 腾讯云服务器部署 django项目整个流程

    CentOS7下部署Django项目详细操作步骤 前记:购买腾讯云服务器,配置自选,当然新用户免费体验半个月,我选择的系统是centos7系统版本, 接下来我们来看整个配置项目流程. 部署是基于:ce ...

  8. 三、Django安装和流程

    一.MVC模式 MVC(Model-View-Controller),中文名“模型-视图-控制器”,是一个好的Web应用开发所遵循的模式,它有利于把Web应用的代码分解为易于管理的功能模块. M:Mo ...

  9. Django -- DRF 认证流程

    Django Restful Framework (DRF)中类的调用与自定义-- 以 autentication 认证为例 DRF 的 request 对 django 的 request 进行了更 ...

随机推荐

  1. 微信小程序教程(第四篇)

    小程序开发基本框架及其限制与优化 开发基本框架(MINA框架) └─ Project-folder/ ·································· 项目所在目录 ├─ page ...

  2. .Net程序员学用Oracle系列(11):系统函数(下)

    1.聚合函数 1.1.COUNT 函数 1.2.SUM 函数 1.3.MAX 函数 1.4.MIN 函数 1.5.AVG 函数 2.ROWNUM 函数 2.1.ROWNUM 函数简介 2.2.利用 R ...

  3. SpringMVC通过实体类返回json格式的字符串,并在前端显示

    一.除了搭建springmvc框架需要的jar包外,还需要这两个jar包 jackson-core-asl-1.9.2.jar和jackson-mapper-asl-1.9.2.jar 二.web,. ...

  4. NodeJS Stream 五:双工流

    双工流就是同时实现了 Readable 和 Writable 的流,即可以作为上游生产数据,又可以作为下游消费数据,这样可以处于数据流动管道的中间部分,即 rs.pipe(rws1).pipe(rws ...

  5. jquery的deferred异步

    推荐方法: var wait = function(dtd){ var dtd = $.Deferred(); //在函数内部,新建一个Deferred对象 var tasks = function( ...

  6. vue.js 常用语法总结(一)

    作者:曾萍,目前就职于京东商城. 概述 2016年已经结束了.你是否会思考一下,自己在过去的一年里是否错过一些重要的东西?不用担心,我们正在回顾那些流行的趋势.通过比较过去12个月里Github所增加 ...

  7. Linux文件权限及用户管理

    /etc/passwd文件与 /etc/shadow文件/etc/passwd文件/etc/passwd文件主要存放登录名.UID等用户相关信息,用户登录密码存放在/etc/shadow文件中.例子: ...

  8. 众人拾柴火焰高之Tomcat集群

    一人拾柴火不旺,众人拾柴火焰高.Tomcat服务器也是一样,一台服务器再强大能承受的访问也是有限的.要提供高并发.高可用的服务,就必须横向扩展,多台Tomcat组成一个集群,根据实际的访问量动态增减服 ...

  9. PHP面向对象编程简单实例

     <?php date_default_timezone_set("PRC"); /** 1.静态属性用于保存类的公有数据* 2.静态方法里面只能访问静态属性* 3.静态成员 ...

  10. matlab 嵌套循环的学习

    循环嵌套带嵌套的循环一般为两重,举例1: disp('一个简单的二重for循环'); : : result = ii *jj ; fprintf(' %d * %d = %d \n',ii,jj,re ...