Django之生命周期

前台发送URL请求到Django的中间件进行内容校验,完成校验后到达路由映射文件url.py,然后调用视图函数views.py里面的函数进行内容处理【 1.操作数据库进行数据读写  2. 调用前台的模版内容】最后返回字符串给前台进行页面的渲染【这里回去的时候也会经过中间件】。

Django之中间件

【更多参考】http://www.cnblogs.com/wupeiqi/articles/5246483.html

Django中间件类似于Java框架中的拦截器之类的东西,就是在请求到达我们要操作的函数之前添加的一些判断之类的操作。

应用场景: 适用于全局的操作,对所有的用户请求/用户返回数据都需要处理的情况。process_request适用于请求到达之前已经执行的操作,类似防护的操作[例如,csrf中间件,过滤器,自定义请求头];

Django中间件即类中的方法执行顺序是Django固定的,不能更改执行顺序,函数名称也不能更改【如果自定义了MiddlewareMixin的话,可以不使用固定的名称】

注:这里的函数是不需要全部写的,也就是process_request和process_response可有可无

中间件中可以定义四个方法,分别是:

process_request(self,request)

process_view(self, request, callback, callback_args, callback_kwargs)

process_template_response(self,request,response)

process_exception(self, request, exception)

process_response(self, request, response)

中间件实例

创建中间件路径【文件夹+文件】

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',
'plugin.handler.Handler',
'plugin.handler.Handler2',
'plugin.handler.Handler3',
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('test/', views.Test),
url('test/(\d+)/', views.Test1),
# url('test/(?P<nid>\d{3})/', views.Test2), # 效果同Test1,只不过nid的名称是固定,kv形式返回
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# 中间层操作
class Foo:
def __init__(self, request, html):
self.req = request
self.html = html def render(self):
return render(self.req, self.html) def Test(request):
print('views')
return HttpResponse("OK") def Test1(request,nid):
print('views1')
return HttpResponse("OK1") def Test2(request, nid):
print('views2')
return HttpResponse("OK2") # 测试process_template_response,这里不做细节演示
def Test4(request, nid):
print('views2')
return Foo(request, 'test.html')

plugin/handler.py

# version: python3.2.5
# 中间件测试
# 新的中间件【复制的原类,为了规范起见,所有中间件继承于此】
# 另:继承了自定义的MiddlewareClass就可以自定义函数名了,不一定是process_request
class MiddlewareClass(object):
def __init__(self, get_response=None):
self.get_response = get_response
super(MiddlewareClass, self).__init__() def __call__(self, request):
response = None
if hasattr(self, 'process_request'):
# 执行当前中间件的process_request
response = self.process_request(request)
if not response:
# 执行下一个中间件的__call__()方法
response = self.get_response(request)
if hasattr(self, 'process_response'):
# 执行当前中间件的process_response
response = self.process_response(request, response)
return response from django.utils.deprecation import MiddlewareMixin # 原始的继承类
from django.shortcuts import HttpResponse
class Handler(MiddlewareClass):
def process_request(self, request):
print('A --> process_request')
# return HttpResponse("Handler的process_response结束了请求...") #Django2.0.1中此方法会终止后面的中间件请求 # 根据url.py里面的路由映射获取views.py里面的函数,函数参数
# view_func: 函数名
# view_args:参数名
# view_kwargs: 如果参数名指定了列名,则key-value形式显示
# 执行的时候会按照A->B->C的顺序依次执行中间件内容,完成后去执行process_exception
def process_view(self, request, view_func, view_args, view_kwargs):
print('A --> process_view') # 这个函数只对views.py里面的报错进行处理,其他异常均不处理
# 异常处理完成后返回到最后一个中间件process_response进行response处理
def process_exception(self, request, exception):
print('A --> process_exception') def process_response(self, request, response):
print('A --> process_response')
return response # views.py函数如果返回的是HttpResponse("OK1"),则这个函数并不做什么操作
# views.py函数如果返回的是Render(request, 'index.html'),则这个函数也不做什么操作
# views.py函数如果返回的对象new Obj()有Render方法,则这个函数会去render函数里面做操作
def process_template_response(self, request, response):
print('A --> process_template_response')
return response class Handler2(MiddlewareClass):
def process_request(self, request):
print('B --> process_request') def process_view(self, request, view_func, view_args, view_kwargs):
print('B --> process_view')
print('view_func:', view_func)
print('view_args:', view_args)
print('view_kwargs:', view_kwargs) def process_exception(self, request, exception):
print('B --> process_exception') def process_response(self, request, response):
print('B --> process_response')
print("Response类型:", response)
print("Response类型:", type(response))
return response def process_template_response(self, request, response):
print('B --> process_template_response')
return response class Handler3(MiddlewareClass):
def process_request(self, request):
print('C --> process_request') def process_view(self, request, view_func, view_args, view_kwargs):
print('C --> process_view') def process_exception(self, request, exception):
print('C --> process_exception') def process_response(self, request, response):
print('C --> process_response')
return response def process_template_response(self, request, response):
print('C --> process_template_response')
return response

templates/XXX.html

页面显示;

正常访问执行顺序:

中间件request请求中返回response效果:

另外其他的函数执行效果:

Django之CSRF[跨站请求伪造]

Django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成。而对于django中设置防跨站请求伪造功能有分为全局和局部。

全局:

  中间件 django.middleware.csrf.CsrfViewMiddleware

局部:

@csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。

@csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。

注: from django.views.decorators.csrf import csrf_exempt,csrf_protect

settings.py里面如果未注释掉CSRF验证【即需要CSRF验证】

我们的get请求可以通过,post请求会被拦截

Django里面使用form的post请求发送数据的时候,一定是return了一个render对象,且HTML的form表单内使用了{% csrf_token %}进行标记,此时前台的HTML里面会多出一行csrf的token同时会缓存一份到Cookie里面。同理,如果我们需要ajax发送post请求的时候,是需要从Cookie里面获取token[从截图可以看到Cookie里面token的key是csrftoken]并添加到请求头[request-header]里让Django进行验证的。

Ajax请求CSRF实例

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
MIDDLEWARE = [
...
'django.middleware.csrf.CsrfViewMiddleware',
...
] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('login/', views.Login),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# SCRF测试
def Login(request):
# 注意这里的settings是Django默认的
# 我们看到的写入的settings.py文件会读入并覆盖conf里面的setting
from django.conf import settings
print('settings.CSRF_HEADER_NAME: ', settings.CSRF_HEADER_NAME)
print(request.method)
return render(request, 'login.html')

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<form action="/login/" method="post">
{% csrf_token %}
姓名:<input type="text" name="username">
<input type="submit" value="Form提交">
<input type="button" value="Ajax提交" id="btn">
</form>
</body>
<script src="/static/jquery-2.1.4.min.js"></script>
<script src="/static/JQuery.Cookies.js"></script>
<script>
$(function () {
{# 这里对请求头做统一的处理,发送请求之前进行批量的配置 #}
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
}
});
$("#btn").click(function () {
$.ajax({
url: '/login/',
type:'POST',
{# headers: {'X-CSRFTOKEN': 'hhh'},#}
{# headers: {'X-CSRFTOKEN': $.cookie('csrftoken')}, 这里是自定义添加token#}
data: {username: 'root'},
success: function (args) {
console.log(args)
}
})
})
})
</script>
</html>

PS: 获取request里面的请求信息,可以使用断点打印,我们可以看出我们request里的header经过Django处理后在Meta里面呢,且字段名前添加了HTTP的前缀。

页面显示;

其他

Django之缓存

【更多参考】http://www.cnblogs.com/wupeiqi/articles/5246483.html

由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时,则不再去执行view中的操作,而是直接从内存或者Redis中之前缓存的内容拿到,并返回。

缓存适用于固定内容且访问量大,大型文件内容,不具有实时性的内容。

缓存方式及配置

Django中提供了6种缓存方式:

开发调试 -->  什么都不干

内存

文件

数据库

Memcache缓存(python-memcached模块)   -->在另外一台服务器上

Memcache缓存(pylibmc模块)

配置:

开发调试

# 此为开始调试用,实际内部不做任何操作
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
},
'KEY_PREFIX': '', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION' 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}
注:memache帮我们生成key的时候,会以前缀+版本+key为默认key名称,具体看下面源码
# 自定义key
def default_key_func(key, key_prefix, version):
"""
Default function to generate keys.
Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
"""
return '%s:%s:%s' % (key_prefix, version, key) def get_key_func(key_func):
"""
Function to decide which key function to use.
Defaults to ``default_key_func``.
"""
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func

内存:

# 此缓存将内容保存至内存的变量中
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',# 此参数就是标志唯一变量名称用于指引value可任意指定
}
} # 注:其他配置同开发调试版本

文件:

# 此缓存将内容保存至文件
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache', # 指定文件路径,文件存放位置
}
}
# 注:其他配置同开发调试版本

数据库:

# 此缓存将内容保存至数据库
# 配置:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 指定数据库表,一条数据就是一个缓存
}
}
# 注:执行创建表命令 python manage.py createcachetable -->专门防止缓存的表

Memcache缓存(python-memcached模块)

Memcache可以理解为另外一个服务器的内存,是内存级别的缓存;

内容以Key-Value形式存储,整体的Memcache就是一个大字典

# 此缓存使用python-memcached模块连接memcache
# 3种连接方式
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211', # 根据IP和端口连接指定机器
}
}
# 此方法只能连接本机信息
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock', # 以文件的形式连接[文件包含连接信息]
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
('172.19.26.240:11211', 10), # 连接多个服务器,类似分布式哈~
('172.19.26.242:11211', 15), # 数据存储再多个服务器上...
('172.19.26.241:11211,’ 20), # 设置了权重的连接,用户输入的key会计算hash值,返回一个int数字,后根据取余求算存储位置,根据权重确定服务器。加了权重后的,此时相当于10+15+20个服务器了,写入第三个服务器[有20个]的概率大
]
}
}

Memcache缓存(pylibmc模块)

# 此缓存使用pylibmc模块连接memcache
# 共3种连接方式
# 解释同上
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

注:memache中如果有服务器故障,因为memacahe里面没有检测机制,只能自己监控该模块,更改模块里面的接口方法处理

缓存应用

Django中提供了3种缓存方式:

全栈使用缓存

单独视图缓存

局部视图使用

A. 全栈使用的配置

settings.py

MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 其他中间件...
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS = ""
CACHE_MIDDLEWARE_SECONDS = ""
CACHE_MIDDLEWARE_KEY_PREFIX = ""

B.单独视图缓存

settings.py

方式一:
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
方式二:
from django.views.decorators.cache import cache_page
urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]

C.局部视图缓存

Html文件内写

a. 引入TemplateTag
{% load cache %}
b. 使用缓存
{% cache 5000 缓存key %}
缓存内容
{% endcache %}

单独视图和局部视图实例

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
MIDDLEWARE = [
...
# 'django.middleware.csrf.CsrfViewMiddleware',
...
] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR, 'cache'), # 指定文件路径,文件存放位置
}
}

urls.py

from django.contrib import admin
from django.urls import path
from django.conf.urls import url, include
from app01 import views
urlpatterns = [
url('cache/', views.Cache),
url('part/', views.Cache_part),
]

views.py

from django.shortcuts import render, redirect, HttpResponse
from app01 import models
# 文件缓存之单独视图[views]缓存 -->缓存整个页面及内容
from django.views.decorators.cache import cache_page
@cache_page(10)
def Cache(request):
import time
v = time.time()
return HttpResponse(v) # 文件缓存之局部视图缓存 -->缓存部分页面内容
def Cache_part(request):
import time
v = time.time()
return render(request, 'part.html', {'v':v})

templates/part.html

{% load cache %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>H1:{{ v }}</h1>
{% cache 10 time %}
<h5>H5: {{ v }}</h5>
{% endcache %}
</body>
</html>

页面显示;

文件缓存之单独视图缓存 :

文件缓存之局部视图缓存

全栈使用实例

settings.py

INSTALLED_APPS = [
...
'app01', # 注册app
]
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware', ] STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),) # 现添加的配置,这里是元组,注意逗号
TEMPLATES = [
...
'DIRS': [os.path.join(BASE_DIR, 'templates')],
]
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': os.path.join(BASE_DIR, 'cache'), # 指定文件路径,文件存放位置
}
}

其余同部分的单独的使用...

页面显示;

全栈中间件代码分析:

from django.middleware.cache import FetchFromCacheMiddleware

from django.middleware.cache import UpdateCacheMiddleware

Django之bootStrap

bootStrap 一个集成css,js的文件

【bootStrap参考】  http://v3.bootcss.com/getting-started/

【更多参考】http://www.cnblogs.com/wupeiqi/articles/5237704.html

Python学习---Django拾遗180328的更多相关文章

  1. Python学习---django模板语法180122

    django模板语法[Template] 模版的组成:  HTML代码+逻辑控制代码  <h1> {{ user_name }} </h1> 逻辑控制代码的组成: 1.变量: ...

  2. Python学习---Django下的Sql性能的测试

    安装django-debug-tools Python学习---django-debug-tools安装 性能测试: settings.py INSTALLED_APPS = [ ... 'app01 ...

  3. python学习-- Django根据现有数据库,自动生成models模型文件

    Django引入外部数据库还是比较方便的,步骤如下 : 创建一个项目,修改seting文件,在setting里面设置你要连接的数据库类型和连接名称,地址之类,和创建新项目的时候一致 运行下面代码可以自 ...

  4. Python学习---django下的cookie操作 180201

    什么是Cookies 什么是Cookies cookies设置的原因: 1. http请求的无记忆性: 2.加快访问速度  3. 减少服务器压力 cookies特点: cookies保存在客户端浏览器 ...

  5. Python学习---django之ORM语法[对象关系映射]180124

    ORM语法[对象关系映射] ORM: 用面向对象的方式去操作数据库的创建表以及增删改查等操作. 优点:1 ORM使得我们的通用数据库交互变得简单易行,而且完全不用考虑该死的SQL语句.快速开发. 2 ...

  6. Python学习---Django的基础学习

    django实现流程 Django学习框架:     #安装: pip3 install django          添加环境变量    #1  创建project       django-ad ...

  7. Python学习---Model拾遗[1]180318

    Model: 强大的数据库操作,弱小的数据验证 Form:  强大的数据验证 ModelForm: 强大的数据验证 + 弱小的数据库操作 Model拾遗 Model基本操作 1. 创建数据库表2. 修 ...

  8. [Python学习] Django 权限控制

    本文为大家讲解 Django 框架里自带的权限模型,从理论到实战演练,带领大家了解 Django 里权限是怎么一回事. 一.主要内容 1.什么是权限管理? 2.Web 权限 3.Django 权限机制 ...

  9. python学习--Django虚拟环境搭建

    一 . 为什么选择搭建虚拟环境 搭建一个只对本次项目有用的虚拟环境,而不影响主环境 二 . 安装前准备 #    1. 安装 python #    2. 安装virtualenvwrapper #  ...

随机推荐

  1. centos7-默认启动方式改变

    在图形界面使用 ctrl+alt+F2切换到dos界面 dos界面 ctrl+alt+F2切换回图形界面 在命令上 输入 init 3 命令 切换到dos界面 输入 init 5命令 切换到图形界面 ...

  2. 一个快速搜索下载jar包的网站

    在偶然的机会,我一个快速搜索下载jar包的网站.里面涵盖了所有的几乎全世界开源的jar包,感觉这个功能特别适合java.android开发者使用,共享出来給大家悄悄. 百度一下:manyjar,就可以 ...

  3. RabbitMQ上手记录–part 5-节点集群高可用(多服务器)

    上一part<RabbitMQ上手记录–part 4-节点集群(单机多节点)>中介绍了RabbitMQ集群的一些概念以及实现了在单机上运行多个节点,并且将多个节点组成一个集群. 通常情况下 ...

  4. Asp.net MVC中关于@Html标签Label、Editor使用

    @Html帮助器简单说明,记录些基本的跟HTML中对应的@html帮助器,@Html基本包含了html中的表单控件和常用Html在@Html中,带有For的主要是针对强类型的Html类型.用于说明@H ...

  5. [转]UI-Grid HeaderCellClass

    本文转自:http://blog.csdn.net/vesong87/article/details/69230476 原文: 115 HeaderCellClass 在columnDef中可以为每个 ...

  6. ABP学习入门系列(五)(展示实现增删改查)

    大致要实现的 效果如下 1,添加Controller(用到的X.PagedList 注意到nuget添加) using System.Web.Mvc; using Abp.Application.Se ...

  7. MyBatis源码解析之数据源(含数据库连接池简析)

    一.概述: 常见的数据源组件都实现了javax.sql.DataSource接口: MyBatis不但要能集成第三方的数据源组件,自身也提供了数据源的实现: 一般情况下,数据源的初始化过程参数较多,比 ...

  8. javaweb开发之get与post请求的区别

    GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二. 最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数. 你可能自己 ...

  9. IDEA 的 properties 文件的属性字段如何链接到调用的文件

    想要达到的效果: ctrl + 鼠标点击:弹出如下所有使用的文件 问题: 有些 IDEA 使用 ctrl + 鼠标点击不能看到使用的文件. 解决办法: ctrl + 鼠标点击,然后选择设置按钮 然后 ...

  10. 为什么要用 C# 来作为您的首选编程语言

    因为您可以用,并且也是您的最佳选择!之所以可用,是因为 C# 能够很好地在 Mac.Linux.Android 和 iOS 上运行(对了,还有 Windows):它可以在您最喜爱的编辑器上运行:它在一 ...