django框架--底层架构

目录

  • 零、参考
  • 一、对于web服务的理解
  • 二、对于wsgi协议的理解
  • 三、自定义一个简单的基于wsgi协议的web框架
  • 四、django中的server实现
  • 五、django中的application实现
  • 六、django的底层调用链
  • 七、总结

零、参考

https://www.jianshu.com/p/679dee0a4193
https://www.letiantian.me/2015-09-10-understand-python-wsgi/

一、对于web服务的理解

web服务应该至少包含两个模块:web服务器和web应用程序,两个模块在功能和代码上解耦。
web服务器负责处理socket调用、http数据解析和封装等底层操作。
web应用程序负责业务处理、数据增删改查、页面渲染/生成等高层操作。
web服务器一旦接收到http请求,经过自身的解析后就会调用web应用程序来处理业务逻辑,并得到web应用程序的返回值,再经过自身的封装发送给客户端。

二、对于wsgi协议的理解

web服务器和web应用程序之间需要定义一个接口规则,这也叫协议,用于明确两者之间以什么样的形式交互数据。即:web服务器应该以什么样的形式调用web应用程序,而web应用程序又应该定义成什么形式。

python下规定的web服务的接口规则叫做wsgiwsgi协议对于serverapplication的接口定义如下:

对于server调用规则的定义:

response = application(environ, start_response) 

对于application接口编码的定义:

def application(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-Type', 'text/plain'),]
    start_response(status, response_headers)

    return [b'hello',]

只要是遵从如上形式进一步封装serverapplication的,均称为实现了wsgi协议的server/application

python内置提供了一个wsigref模块用于提供server,但是只能用于开发测试,django框架就是使用此模块作为它的server部分,也就说,实际生产中的server部分,还需要使用其他模块来实现。

任何web框架,可能没有实现server部分或者只实现一个简单的server,但是,web框架肯定实现了application部分。application部分完成了对一次请求的全流程处理,其中各环节都可以提供丰富的功能,比如请求和响应对象的封装、model/template的实现、中间件的实现等,让我们可以更加细粒度的控制请求/响应的流程。

三、自定义一个简单的基于wsgi协议的web框架

django框架的server部分由python内置的wsgiref模块提供,我们只需要编写application应用程序部分。

from wsgiref.simple_server import make_server

def app(environ, start_response):  # wsgi协议规定的application部分的编码形式,可在此基础上扩展
    status = '200 OK'
    respones_headers = []

    start_response(status, response_headers)
    return [b'hello',]

if __name__ == '__main__':
    httpd = make_server('127.0.0.1', 8080, app)
    httpd.serve_forever()

四、django中的server实现

django使用的底层server模块是基于python内置的wsgiref模块中的simple_server,每次django的启动都会执行如下run函数。run函数中会执行serve_forever,此步骤将会启动socket_server的无限循环,此时就可以循环提供请求服务,每次客户端请求到来,服务端就执行django提供的application模块。

djangoserver的启动----django.core.servers.basehttp.py

"""
HTTP server that implements the Python WSGI protocol (PEP 333, rev 1.21).

Based on wsgiref.simple_server which is part of the standard library since 2.5.

This is a simple server for use in testing or debugging Django apps. It hasn't
been reviewed for security issues. DON'T USE IT FOR PRODUCTION USE!
"""

def run(addr, port, wsgi_handler, ipv6=False, threading=False, server_cls=WSGIServer):
    server_address = (addr, port)
    if threading:
        httpd_cls = type('WSGIServer', (socketserver.ThreadingMixIn, server_cls), {})
    else:
        httpd_cls = server_cls
    httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)
    if threading:
        # ThreadingMixIn.daemon_threads indicates how threads will behave on an
        # abrupt shutdown; like quitting the server by the user or restarting
        # by the auto-reloader. True means the server will not wait for thread
        # termination before it quits. This will make auto-reloader faster
        # and will prevent the need to kill the server manually if a thread
        # isn't terminating correctly.
        httpd.daemon_threads = True
    httpd.set_app(wsgi_handler)
    httpd.serve_forever()

底层无限循环将作为web服务的主要驱动----socektserver.py

def serve_forever(self, poll_interval=0.5):
    """Handle one request at a time until shutdown.

    Polls for shutdown every poll_interval seconds. Ignores
    self.timeout. If you need to do periodic tasks, do them in
    another thread.
    """
    self.__is_shut_down.clear()
    try:
        # XXX: Consider using another file descriptor or connecting to the
        # socket to wake this up instead of polling. Polling reduces our
        # responsiveness to a shutdown request and wastes cpu at all other
        # times.
        with _ServerSelector() as selector:
            selector.register(self, selectors.EVENT_READ)

            while not self.__shutdown_request:
                ready = selector.select(poll_interval)
                if ready:
                    self._handle_request_noblock()

                self.service_actions()
    finally:
        self.__shutdown_request = False
        self.__is_shut_down.set()

server对于application的调用----wsgiref.handlers.py

def run(self, application):
    """Invoke the application"""
    # Note to self: don't move the close()!  Asynchronous servers shouldn't
    # call close() from finish_response(), so if you close() anywhere but
    # the double-error branch here, you'll break asynchronous servers by
    # prematurely closing.  Async servers must return from 'run()' without
    # closing if there might still be output to iterate over.
    try:
        self.setup_environ()
        self.result = application(self.environ, self.start_response)
        self.finish_response()
    except:
        try:
            self.handle_error()
        except:
            # If we get an error handling an error, just give up already!
            self.close()
            raise   # ...and let the actual server figure it out.

五、django中的application实现

djangoapplication模块是通过WSGIHandler的一个实例来提供的,此实例可以被call,然后根据wsgi的接口规则传入environstart_response。所以本质上,django就是使用的内置python提供的wsgiref.simple_server再对application进行丰富的封装。大部分的django编码工作都在application部分。

application的编码定义部分----django.core.handlers.wsgi.py

class WSGIHandler(base.BaseHandler):
    request_class = WSGIRequest

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.load_middleware()

    def __call__(self, environ, start_response):
        set_script_prefix(get_script_name(environ))
        signals.request_started.send(sender=self.__class__, environ=environ)
        request = self.request_class(environ)
        response = self.get_response(request)

        response._handler_class = self.__class__

        status = '%d %s' % (response.status_code, response.reason_phrase)
        response_headers = list(response.items())
        for c in response.cookies.values():
            response_headers.append(('Set-Cookie', c.output(header='')))
        start_response(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

六、django的底层调用链

七、总结

web服务是基于socket的高层服务,所以web服务必须含有web服务器这一模块。
web服务需要动态渲染数据,需要中间件来丰富功能,需要封装和解析来处理数据,所以web服务必须含有web应用程序这一模块。
web框架是一种工具集,封装了各种功能的底层代码,提供给我们方便开发的接口。但不论是哪一种框架,它们的底层原理基本都是一致的。
应该深入学习、研究一个web框架,精通一门框架的实现原理和设计理念。

原文地址:https://www.cnblogs.com/zzzlw/p/9747872.html

时间: 2024-10-13 12:23:54

django框架--底层架构的相关文章

MVC其实很简单(Django框架)

Django框架MVC其实很简单 让我们来研究一个简单的例子,通过该实例,你可以分辨出,通过Web框架来实现的功能与之前的方式有何不同. 下面就是通过使用Django来完成以上功能的例子: 首先,我们分成4个Python的文件,(models.py , views.py , urls.py ) 和html模板文件 (latest_books.html ). models.py: # models.py (the database tables) from django.db import mod

Python的Django框架中的Cookie相关处理

Python的Django框架中的Cookie相关处理 浏览器的开发者在很早的时候就已经意识到, HTTP's 的无状态会对Web开发者带来很大的问题,于是(cookies)应运而生. cookies 是浏览器为 Web 服务器存储的一小段信息. 每次浏览器从某个服务器请求页面时,它向服务器回送之前收到的cookies 来看看它是怎么工作的. 当你打开浏览器并访问 google.com ,你的浏览器会给Google发送一个HTTP请求,起始部分就象这样: GET / HTTP/1.1 Host:

Django框架基础

Django基础-Lesson1 web框架概念 框架,即framework,特指为解决一个开放性问题而设计的具有一定约束性的支撑结构,使用框架可以帮你快速开发特定的系统. 对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端.  socket模拟服务端 最简单的Web应用就是先把HTML用文件保存好,用一个现成的HTTP服务器软件,接收用户请求,从文件中读取HTML,返回. 如果要动态生成HTML,就需要把上述步骤自己来实现.不过,接受HTTP

那些年我们一起玩的Django框架之全面讲解

Web框架之Django: (1)简介: Django是一个由Python写成开源的重量级Web应用框架,采用MTV的框架模式.它最初是被开发来用于管理劳伦斯出版集团旗下的一些以新闻内容为主的网站的,即是CMS(内容管理系统)软件.并于2005年7月在BSD许可证下发布.这套框架是以比利时的吉普赛爵士吉他手Django Reinhardt来命名的.Django的优势在于:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. (2)Django的处理流程: 1.   

Django框架的简介

Django框架的背景 Django是一款基于Python开发的全栈式一体化Web 应用框架.2003 年问世之初,它只是 美国一家报社的内部工具,2005 年 7 月使用 BSD 许可证完成了开源.其目的是削减代码量,简 单且迅速地搭建以数据库为主体的复杂Web 站点.它是全栈式框架,因此安装起来很简单,而 且使用者众多.这使得 Django除具有完备的官方文档之外,还有大量的关联文档.丰富的第三 方库可供使用.与其他框架相比,Django 用起来要轻松得多. Django框架的特点 1.完整

[Python] Django框架入门5——静态文件、中间件、上传图片和分页

说明: 本文主要描述Django其他的内容,涉及静态文件处理.中间件.上传文件.分页等. 开发环境:win10.Python3.5.Django1.10. 一.静态文件处理 在Django项目的静态文件主要指的是css.js和图片等文件. 1.配置静态文件 在settings.py文件中配置静态内容: STATIC_URL:在html文件中使用的路径,如:"/static/images/logo.png". STATICFILES_DIRS:指静态文件在项目的存放位置. 2.新建目录

Django框架之中间件MiddleWare

Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出.中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性.我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预. 中间件的原理其实就是定义了一个装饰器,但是这个装饰器可以对整个项目中的所有方法进行装饰: 我们可以通过中间件,对请求对象和响应对象进行相应的干预操作. 实现中间件的流程: 1.在子应用中编写一个middleware.p

Django框架介绍 python三大主流web框架之一

一.学习准备 1.下载安装Django(建议安装1.x版本) 方法:终端cmd输入命令:pip install django==1.11.11  然后回车即可 校验是否安装成功:django-admin 二.纯手撸web框架 1.纯手撸web框架 软件开发架构 c/s架构 b/s架构 本质bs也是cs web后端 需求: 1.根据用户输入不同的后缀返回不同的内容 从符合http协议格式的数据中获取用户输入的后缀 不足之处: 1.socket代码是我们自己写的 2.http数据也是我们自己处理的

python后端面试第四部分:django框架--长期维护

##################    Python语法基础        ####################### django框架部分 1,流程 2,admin 3,视图 3,路由 4,csrf 3.csrf是什么?django是如何防范的? django请求的生命周期, 浏览器-wsgi-中间件-路由-视图-然后处理数据等,返回数据 3,什么是wsgi?是一个协议,还有一些需要理解, 4,中间件是什么?在视图之前定制一些操作, 5,使用中间件做什么?做过什么认证,权限,跨域,等,