drf学习之Django进阶点

一.Django migrations原理

1.makemigrattions:

相当于在每个app下的migrations文件夹下生成一个py脚本文件用于创建表或则修改表同步modes.py的改动,还未作用到数据库比如0001_initial.py,可以用python manger.py sqlmigrate theapp 0001查看文件中对应的sql命令。

2.migrate:

在每个app下的migrations下查找对应的py文件脚本运行同步到数据库,但做了很多次改变后里面有很对文件如何找到对应的oy文件并且只运行它,这就要依靠django_migrations这张表,里面详细的记录了运行了migrations下的哪些文件,执行migrate时会在这张表中查找运行了哪些文件,如果找到就会跳过不运行。如果执行migrate未执行脚本,有可能已经运行过了,就可以到表中查看对应记录及表删除从新运行。

二.Django信号量

三.Django从请求到响应的完整过程

1.runserver:

    ruserver是使用django自己的web server,主要用于开发和调试中, 部署到线上环境一般使用nginx+uwsgi模式.

 2.manage.py   

   看一下manager.py的源码,你会发现上面的命令其实是通过Django的execute_from_command_line方法执行了内部实现的runserver命令,那么现在看一下runserver具体做了什么。 

   通过源码分析可知, ruserserver主要完成两件事:

      1). 解析参数,并通过django.core.servers.basehttp.get_internal_wsgi_application方法获取wsgi handler;
      2). 根据ip_address和port生成一个WSGIServer对象,接受用户请求
    get_internal_wsgi_application的源码如下:
      通过上面的代码我们可以知道,Django会先根据settings中的WSGI_APPLICATION来获取handler;
      在创建project的时候,Django会默认创建一个wsgi.py文件,而settings中的WSGI_APPLICATION配置也会默认指向这个文件。看一下这个wsgi.py文件,其实它也和上面的逻辑一样,最终调用get_wsgi_application实现。

3.django http请求处理流程(摘抄http://www.projectsedu.com,更多详细请点击):

    Django和其他Web框架一样,HTTP的处理流程基本类似:接受request,返回response内容。Django的具体处理流程大致如下:

      3.1 加载settings.py:     

        在通过django-admin.py创建project的时候,Django会自动生成默认的settings文件和manager.py等文件,在创建WSGIServer之前会执行下面的引用:

        from django.conf import settings

        上面引用在执行时,会读取os.environ中的DJANGO_SETTINGS_MODULE配置,加载项目配置文件,生成settings对象。所以,在manager.py文件中你可以看到,在获取WSGIServer之前,会先将project的settings路径加到os路径中。

     3.2 创建WSGIServer:

      不管是使用runserver还是uWSGI运行Django项目,在启动时都会调用django.core.servers.basehttp中的run()方法
      创建一个django.core.servers.basehttp.WSGIServer类的实例,之后调用其serve_forever()方法启动HTTP服务。run方法的源码如下:
def run(addr, port, wsgi_handler, ipv6=False, threading=False):
server_address = (addr, port)
if threading:
httpd_cls = type(str('WSGIServer'), (socketserver.ThreadingMixIn, WSGIServer), {})
else:
httpd_cls = WSGIServer
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()

      如上,我们可以看到:在创建WSGIServer实例的时候会指定HTTP请求的Handler,
      上述代码使用WSGIRequestHandler。当用户的HTTP请求到达服务器时,
      WSGIServer会创建WSGIRequestHandler实例,使用其handler方法来处理HTTP请求(其实最终是调用wsgiref.handlers.BaseHandler中的run方法处理)。
      WSGIServer通过set_app方法设置一个可调用(callable)的对象作为application,上面提到的handler方法最终会调用设置的application处理request,并返回response。
      其中,WSGIServer继承自wsgiref.simple_server.WSGIServer,而WSGIRequestHandler继承自wsgiref.simple_server.WSGIRequestHandler,wsgiref是Python标准库给出的WSGI的参考实现。其源码可自行到wsgiref参看,这里不再细说。

    3.2处理Request:

      第二步中说到的application,在Django中一般是django.core.handlers.wsgi.WSGIHandler对象,WSGIHandler继承自django.core.handlers.base.BaseHandler,这个是Django处理request的核心逻辑,它会创建一个WSGIRequest实例,而WSGIRequest是从http.HttpRequest继承而来.  

        3.3 返回Response:

      上面提到的BaseHandler中有个get_response方法,该方法会先加载Django项目的ROOT_URLCONF,然后根据url规则找到对应的view方法(类),view逻辑会根据request实例生成并返回具体的response。

      在Django返回结果之后,第二步中提到wsgiref.handlers.BaseHandler.run方法会调用finish_response结束请求,并将内容返回给用户

4.Django处理Request的详细流程:

    4.1lDjango流程图一:

      4.2Django流程图二:

4.3上面的两张流程图可以大致描述Django处理request的流程,按照流程图2的标注,可以分为以下几个步骤:

      1. 用户通过浏览器请求一个页面
      2.请求到达Request Middlewares,中间件对request做一些预处理或者直接response请求
      3.URLConf通过urls.py文件和请求的URL找到相应的View
      4.View Middlewares被访问,它同样可以对request做一些处理或者直接返回response
      5.调用View中的函数
      6.View中的方法可以选择性的通过Models访问底层的数据
      7.所有的Model-to-DB的交互都是通过manager完成的
      8.如果需要,Views可以使用一个特殊的Context
      9.Context被传给Template用来生成页面
         a.Template使用Filters和Tags去渲染输出
         b.输出被返回到View
         c.HTTPResponse被发送到Response Middlewares
         d.任何Response Middlewares都可以丰富response或者返回一个完全不同的response
         e.Response返回到浏览器,呈现给用户
      
    上述流程中最主要的几个部分分别是:Middleware(中间件,包括request, view, exception, response),URLConf(url映射关系),Template(模板系统),下面一一介绍一下。 
      4.3.1Middleware(中间件):
      Middleware并不是Django所独有的东西,在其他的Web框架中也有这种概念。在Django中,Middleware可以渗入处理流程的四个阶段:request,view,response和exception,相应的,在每个Middleware类中都有rocess_request,process_view, process_response 和 process_exception这四个方法。你可以定义其中任意一个活多个方法,这取决于你希望该Middleware作用于哪个处理阶段。每个方法都可以直接返回response对象。

      Middleware是在Django BaseHandler的load_middleware方法执行时加载的,加载之后会建立四个列表作为处理器的实例变量:

        _request_middleware:process_request方法的列表

        _view_middleware:process_view方法的列表

        _response_middleware:process_response方法的列表

        _exception_middleware:process_exception方法的列表

      Django的中间件是在其配置文件(settings.py)的MIDDLEWARE_CLASSES元组中定义的。在MIDDLEWARE_CLASSES中,中间件组件用字符串表示:指向中间件类名的完整Python路径。例如

        `MIDDLEWARE_CLASSES = [
         'django.middleware.security.SecurityMiddleware',
         'django.contrib.sessions.middleware.SessionMiddleware',
         'django.middleware.common.CommonMiddleware',
         'django.middleware.csrf.CsrfViewMiddleware',
         'django.contrib.auth.middleware.AuthenticationMiddleware',
         'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
         'django.contrib.messages.middleware.MessageMiddleware',
         'django.middleware.clickjacking.XFrameOptionsMiddleware',
            ]`       Django项目的安装并不强制要求任何中间件,如果你愿意,MIDDLEWARE_CLASSES可以为空。中间件出现的顺序非常重要:在request和view的处理阶段,Django按照MIDDLEWARE_CLASSES中出现的顺序来应用中间件,而在response和exception异常处理阶段,Django则按逆序来调用它们。也就是说,Django将MIDDLEWARE_CLASSES视为view函数外层的顺序包装子:在request阶段按顺序从上到下穿过,而在response则反过来。以下这张图可以更好地帮助你理解:
   4.3.2URLConf(URL映射):
      如果处理request的中间件都没有直接返回response,那么Django会去解析用户请求的URL。URLconf就是Django所支撑网站的目录。它的本质是URL模式以及要为该URL模式调用的视图函数之间的映射表。通过这种方式可以告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。具体的,在Django项目的配置文件中有ROOT_URLCONF常量,这个常量加上根目录"/",作为参数来创建django.core.urlresolvers.RegexURLResolver的实例,然后通过它的resolve方法解析用户请求的URL,找到第一个匹配的view。

      有关urlconf的内容,大家可以参考 [理解curlConf]()
    4.3.3Template(模板):
      大部分web框架都有自己的Template(模板)系统,Django也是。但是,Django模板不同于Mako模板和jinja2模板,在Django模板不能直接写Python代码,只能通过额外的定义filter和template tag实现。由于本文主要介绍Django流程,模板内容就不过多介绍。

四.独立使用Django的Model

1.导入数据:

# _*_ encoding:utf-8 _*_
__author__ = 'LYQ'
__data__ = '2018/8/17 19:30' #独立使用django的model
import sys
import os #获取当前脚本文件的目录
pwd=os.path.dirname(os.path.realpath(__file__))
#将项目的根目录加入到搜索路径下
sys.path.append(pwd+'../')
#如果要单独使用django的model,必须导入django的环境变量,与项目的setting文件一致,django依赖里面的一些设置文件(因为设置了根目录,所以这样就能找到)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "Vueshops.settings") import django
django.setup()
#位置要放对,配置好引入,不然会报错,很多东西还未配置好
from goods.models import GoodsCategory
from db_tools.data.category_data import row_data for lev1_cat in row_data:
lev1_instance=GoodsCategory()
lev1_instance.code=lev1_cat['code']
lev1_instance.name=lev1_cat['name']
lev1_instance.category_type=1
lev1_instance.save() for lev2_cat in lev1_cat['sub_categorys']:
lev2_instance = GoodsCategory()
lev2_instance.code = lev2_cat['code']
lev2_instance.name = lev2_cat['name']
lev2_instance.category_type = 2
lev2_instance.parent_category=lev1_instance
lev2_instance.save() for lev3_cat in lev2_cat['sub_categorys']:
lev3_instance = GoodsCategory()
lev3_instance.code = lev3_cat['code']
lev3_instance.name = lev3_cat['name']
lev3_instance.category_type = 3
lev3_instance.parent_category = lev2_instance
lev3_instance.save()

Django进阶知识的更多相关文章

  1. Httpd服务进阶知识-LAMP架构概述

    Httpd服务进阶知识-LAMP架构概述  作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.LAMP架构概述 1>.什么是LAM(M)P架构 L: linux A: apa ...

  2. Httpd服务进阶知识-HTTP协议详解

    Httpd服务进阶知识-HTTP协议详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.WEB开发概述 1>.C/S编程 CS即客户端.服务器编程. 客户端.服务端之间需 ...

  3. Spring实战3:装配bean的进阶知识

    主要内容: Environments and profiles Conditional bean declaration 处理自动装配的歧义 bean的作用域 The Spring Expressio ...

  4. Python之路,Day16 - Django 进阶

    Python之路,Day16 - Django 进阶   本节内容 自定义template tags 中间件 CRSF 权限管理 分页 Django分页 https://docs.djangoproj ...

  5. django进阶补充

    前言: 这篇博客对上篇博客django进阶作下补充. 一.效果图 前端界面较简单(丑),有两个功能: 从数据库中取出书名 eg: 新书A 在form表单输入书名,选择出版社,选择作者(多选),输入完毕 ...

  6. django进阶-3

    先看效果图: 登陆admin后的界面: 查看作者: 当然你也可以定制admin, 使界面更牛逼 数据库表结构: app01/models.py from django.db import models ...

  7. django进阶-4

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

  8. Django进阶篇【1】

    注:本篇是Django进阶篇章,适合人群:有Django基础,关于Django基础篇,将在下一章节中补充! 首先我们一起了解下Django整个请求生命周期: Django 请求流程,生命周期: 路由部 ...

  9. django进阶-查询(适合GET4以上人群阅读)

    前言: 下篇博客写关于bootstrap... 一.如何在脚本测试django from django.db import models class Blog(models.Model): name ...

随机推荐

  1. TCP三次握手与四次握手

    背景描述 通过上一篇中网络模型中的IP层的介绍,我们知道网络层,可以实现两个主机之间的通信.但是这并不具体,因为,真正进行通信的实体是在主机中的进程,是一个主机中的一个进程与另外一个主机中的一个进程在 ...

  2. ORA-20011 ORA-29913 KUP-11024 GATHER_TABLE_STATS

    --alter 日志Sat Mar 30 22:01:08 2019DBMS_STATS: GATHER_STATS_JOB encountered errors. Check the trace f ...

  3. P3372 【模板】线段树 1

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个 ...

  4. AGC004F Namori 树形DP、解方程(?)

    传送门 因为不会列方程然后只会树上的,被吊打了QAQ 不难想到从叶子节点往上计算答案.可以考虑到可能树上存在一个点,在它的儿子做完之后接着若干颜色为白色的儿子,而当前点为白色,只能帮助一个儿子变成黑色 ...

  5. Linux 修改时间和时区为上海时区

    发现centos7的时间是utc的,和上海时间不一样. 由于/usr/share/zoneinfo/Asia/  这个目录下没有北京时区,就选择了上海时区,只要赋值过去就可以了 rm -f /etc/ ...

  6. IntelliJ IDEA(一) :安装与破解

    前言 我是从eclipse转IDEA的,对于习惯了eclipse快捷键的我来说,转IDEA开始很不习惯,IDEA快捷键多,组合多,记不住,虽然可以设置使用eclipse的快捷键,但是总感觉怪怪的.开始 ...

  7. Node.js配合jQuery UI autocomplete的应用

    Node.js擅长的领域为: 不需要很多运算 吞吐量要求高 进消息轻并且要求快 出消息轻并且要求快 网上的例子都是socket.io的,我一直在想到底能用在什么地方?根据node.js的优点(擅长领域 ...

  8. jdk1.8之线程中断

    在Core Java中有这样一句话:"没有任何语言方面的需求要求一个被中断的程序应该终止.中断一个线程只是为了引起该线程的注意,被中断线程可以决定如何应对中断 " 线程中断不会使线 ...

  9. 五、xadmin自定义插件2

    以导入插件为例说明: 1.在xadmin-->plugins下面新建excel.py文件 2.新建ListExcelImportPlugin类,继承BaseAdminPlugin from xa ...

  10. centos7 关闭selinux

    关闭SeLinux 临时关闭:setenforce 0 永久关闭:vi /etc/selinux/config