博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python之路-(Django(csrf,中间件,缓存,信号,Model操作,Form操作))
阅读量:5140 次
发布时间:2019-06-13

本文共 5810 字,大约阅读时间需要 19 分钟。

csrf

中间件

缓存

信号

Model操作

Form操作

 

csrf:  

   用 django 有多久,我跟 csrf 这个概念打交道就有久了。

  • 每次初始化一个项目时都能看到 django.middleware.csrf.CsrfViewMiddleware 这个中间件
  • 每次在模板里写 form 时都知道要加一个 {% csrf_token %} tag
  • 每次发 ajax POST 请求,都需要加一个 X_CSRFTOKEN 的 header

什么是 CSRF 

CSRF, Cross Site Request Forgery, 跨站点伪造请求。举例来讲,某个恶意的网站上有一个指向你的网站的链接,如果

某个用户已经登录到你的网站上了,那么当这个用户点击这个恶意网站上的那个链接时,就会向你的网站发来一个请求,

你的网站会以为这个请求是用户自己发来的,其实呢,这个请求是那个恶意网站伪造的。

 

Django 提供的 CSRF 防护机制

django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,

这样就能避免被 CSRF 攻击。

  1. 在返回的 HTTP 响应的 cookie 里,django 会为你添加一个 csrftoken 字段,其值为一个自动生成的 token
  2. 在所有的 POST 表单时,必须包含一个 csrfmiddlewaretoken 字段 (只需要在模板里加一个 tag, django 就会自动帮你生成,见下面)
  3. 在处理 POST 请求之前,django 会验证这个请求的 cookie 里的 csrftoken 字段的值和提交的表单里的 csrfmiddlewaretoken 字段的值是否一样。如果一样,则表明这是一个合法的请求,否则,这个请求可能是来自于别人的 csrf 攻击,返回 403 Forbidden.
  4. 在所有 ajax POST 请求里,添加一个 X-CSRFTOKEN header,其值为 cookie 里的 csrftoken 的值

 

Django 里如何使用 CSRF 防护

  • 首先,最基本的原则是:GET 请求不要用有副作用。也就是说任何处理 GET 请求的代码对资源的访问都一定要是“只读“的。
  • 要启用 django.middleware.csrf.CsrfViewMiddleware 这个中间件
  • 再次,在所有的 POST 表单元素时,需要加上一个 {% csrf_token %} tag
  • 在渲染模块时,使用 RequestContext。RequestContext 会处理 csrf_token 这个 tag,  从而自动为表单添加一个名为 csrfmiddlewaretoken 的 input

 

中间件:

  操作:

  首先在项目里面建立一个文件夹,然后在这个文件夹里面建立一个任意名字的.py文件,这个这个文件基本内容如下:

  

from django.utils.deprecation import MiddlewareMixinclass Row1(MiddlewareMixin):    def process_request(self,request):        print('请求--》代理1')    def process_response(self,request,response):        print('返回--》代理6')        return responseclass Row2(MiddlewareMixin):    def process_request(self,request):        print('请求--》代理2')    def process_response(self,request,response):        print('返回--》代理5')        return responseclass Row3(MiddlewareMixin):    def process_request(self,request):        print('请求--》代理3')    def process_response(self,request,response):        print('返回--》代理4')        return response

  注册:

MIDDLEWARE = [    'django.middleware.security.SecurityMiddleware',    'django.contrib.sessions.middleware.SessionMiddleware',    'django.middleware.common.CommonMiddleware',    'django.middleware.csrf.CsrfViewMiddleware',    'django.contrib.auth.middleware.AuthenticationMiddleware',    'django.contrib.messages.middleware.MessageMiddleware',    'django.middleware.clickjacking.XFrameOptionsMiddleware',    'Middle.m1.Row1',    'Middle.m1.Row2',    'Middle.m1.Row3',]

  

中间件顺序

  一般我们我们从浏览器发出一个请求 Request,得到一个响应后的内容 HttpResponse ,这个请求传递到 Django的过程如下,process request 和 process response的执行顺序正好相反,如下图所示: 

  

 

 

缓存:

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

  

1、准备一个动态网站

urls.py 
from app01 import viewsurlpatterns = [    url(r'^admin/', admin.site.urls),    url(r'^cache/$', views.cache),]

 

cmdb/views.py
import timedef cache(request):    current = str(time.time())    return HttpResponse(current)

 

 

2、创建缓存目录

          

 

3、配置文件

settings.py
CACHES = {    'default': {        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #文件方式        'LOCATION': os.path.join(BASE_DIR, 'cache'),        'TIMEOUT': 600,        'OPTIONS': {            'MAX_ENTRIES': 1000        }    }}

 

4、应用

from django.views.decorators.cache import cache_page @cache_page(60 * 15)    #缓存15分钟def cache(request):    current = str(time.time())    return HttpResponse(current)

 

5、验证

时间戳只刷新了一次就被缓存了起来,再刷新就不改变了,读取的是cache的字符串。同时,生成了2个静态缓存文件:

          

 

信号:

   Django内置信号

  

Model signals    pre_init                    # django的modal执行其构造方法前,自动触发    post_init                   # django的modal执行其构造方法后,自动触发    pre_save                    # django的modal对象保存前,自动触发    post_save                   # django的modal对象保存后,自动触发    pre_delete                  # django的modal对象删除前,自动触发    post_delete                 # django的modal对象删除后,自动触发    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发Management signals    pre_migrate                 # 执行migrate命令前,自动触发    post_migrate                # 执行migrate命令后,自动触发Request/response signals    request_started             # 请求到来前,自动触发    request_finished            # 请求结束后,自动触发    got_request_exception       # 请求异常后,自动触发Test signals    setting_changed             # 使用test测试修改配置文件时,自动触发    template_rendered           # 使用test测试渲染模板时,自动触发Database Wrappers    connection_created          # 创建数据库连接时,自动触发

 

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

from django.core.signals import request_finished    from django.core.signals import request_started    from django.core.signals import got_request_exception    from django.db.models.signals import class_prepared    from django.db.models.signals import pre_init, post_init    from django.db.models.signals import pre_save, post_save    from django.db.models.signals import pre_delete, post_delete    from django.db.models.signals import m2m_changed    from django.db.models.signals import pre_migrate, post_migrate    from django.test.signals import setting_changed    from django.test.signals import template_rendered    from django.db.backends.signals import connection_created    def callback(sender, **kwargs):        print("xxoo_callback")        print(sender,kwargs)    xxoo.connect(callback)    # xxoo指上述导入的内容

 

from django.core.signals import request_finishedfrom django.dispatch import receiver@receiver(request_finished)def my_callback(sender, **kwargs):    print("Request finished!")

 

  自定义信号

1、定义信号

import django.dispatchpizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

 

2、注册信号

def callback(sender, **kwargs):    print("callback")    print(sender,kwargs) pizza_done.connect(callback)

 

3、触发信号

from 路径 import pizza_done pizza_done.send(sender='seven',toppings=123, size=456)

 

Model操作:

 

Form操作:

 

转载于:https://www.cnblogs.com/lei0213/p/6280234.html

你可能感兴趣的文章
Date Picker控件:
查看>>
你的第一个Django程序
查看>>
treegrid.bootstrap使用说明
查看>>
[Docker]Docker拉取,上传镜像到Harbor仓库
查看>>
javascript 浏览器类型检测
查看>>
nginx 不带www到www域名的重定向
查看>>
记录:Android中StackOverflow的问题
查看>>
导航,头部,CSS基础
查看>>
[草稿]挂载新硬盘
查看>>
[USACO 2017 Feb Gold] Tutorial
查看>>
关于mysql中GROUP_CONCAT函数的使用
查看>>
OD使用教程20 - 调试篇20
查看>>
Java虚拟机(JVM)默认字符集详解
查看>>
Java Servlet 过滤器与 springmvc 拦截器的区别?
查看>>
(tmp >> 8) & 0xff;
查看>>
linux命令之ifconfig详细解释
查看>>
NAT地址转换
查看>>
Nhibernate 过长的字符串报错 dehydration property
查看>>
Deque - leetcode 【双端队列】
查看>>
gulp插件gulp-ruby-sass和livereload插件
查看>>