zoukankan      html  css  js  c++  java
  • Python 学习第二十二天 django知识(四)

    一,django session知识

      (1)session与cookies

              session是保存在服务器端的键值对,而cookies是保存在客户浏览器端的特定文件中的键值对

      (2)在用session时,django必须执行两步python manage.py makemigrations,python manage.py migrate 生成相关的session表

      (3)request.session['username']=user 在session中设置值,requset.session['username']在session中获取值

      (4)session 的数据全都保存在服务器端,只给客户端发一份随机字符串,并通过这个随机字符串做验证,session依赖于cookie

      (5)session的配置和操作

             1,数据库session

    Django默认支持Session,并且默认是将Session数据存储在数据库中,即:django_session 表中。
     
    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
         
        SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
        SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
        SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
        SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
        SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
        SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
        SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
     
     
     
    b. 使用
     
        def index(request):
            # 获取、设置、删除Session中数据
            request.session['k1']
            request.session.get('k1',None)
            request.session['k1'] = 123
            request.session.setdefault('k1',123) # 存在则不设置
            del request.session['k1']
     
            # 所有 键、值、键值对
            request.session.keys()
            request.session.values()
            request.session.items()
            request.session.iterkeys()
            request.session.itervalues()
            request.session.iteritems()
     
     
            # 用户session的随机字符串
            request.session.session_key
     
            # 将所有Session失效日期小于当前日期的数据删除
            request.session.clear_expired()
     
            # 检查 用户session的随机字符串 在数据库中是否
            request.session.exists("session_key")
     
            # 删除当前用户的所有Session数据
            request.session.delete("session_key")
     
            request.session.set_expiry(value)
                * 如果value是个整数,session会在些秒数后失效。
                * 如果value是个datatime或timedelta,session就会在这个时间后失效。
                * 如果value是0,用户关闭浏览器session就会失效。
                * 如果value是None,session会依赖全局session失效策略。
    

         2,缓存session

    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
        SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
     
     
        SESSION_COOKIE_NAME = "sessionid"                        # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
        SESSION_COOKIE_PATH = "/"                                # Session的cookie保存的路径
        SESSION_COOKIE_DOMAIN = None                              # Session的cookie保存的域名
        SESSION_COOKIE_SECURE = False                             # 是否Https传输cookie
        SESSION_COOKIE_HTTPONLY = True                            # 是否Session的cookie只支持http传输
        SESSION_COOKIE_AGE = 1209600                              # Session的cookie失效日期(2周)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                   # 是否关闭浏览器使得Session过期
        SESSION_SAVE_EVERY_REQUEST = False                        # 是否每次请求都保存Session,默认修改之后才保存
     
     
     
    b. 使用
     
        同上
    

         3,文件session

    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
        SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()                                                            # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T
     
     
        SESSION_COOKIE_NAME = "sessionid"                          # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
        SESSION_COOKIE_PATH = "/"                                  # Session的cookie保存的路径
        SESSION_COOKIE_DOMAIN = None                                # Session的cookie保存的域名
        SESSION_COOKIE_SECURE = False                               # 是否Https传输cookie
        SESSION_COOKIE_HTTPONLY = True                              # 是否Session的cookie只支持http传输
        SESSION_COOKIE_AGE = 1209600                                # Session的cookie失效日期(2周)
        SESSION_EXPIRE_AT_BROWSER_CLOSE = False                     # 是否关闭浏览器使得Session过期
        SESSION_SAVE_EVERY_REQUEST = False                          # 是否每次请求都保存Session,默认修改之后才保存
     
    b. 使用
     
        同上
    

         4,缓存+数据库session

    数据库用于做持久化,缓存用于提高效率
     
    a. 配置 settings.py
     
        SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
     
    b. 使用
     
        同上
    

        5,加密cookies

    a. 配置 settings.py
         
        SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
     
    b. 使用
     
        同上
    

     二,CSRF知识

      1,CSRF原理

       先访问页面时设置一个随机的字符串,当提交的时候带着生成的随机字符串去提交,则通过CSRF的验证

      2,设置CSRF

        (1)form表单提交,不仅在cookie中生成一个csrftoken,而且在cookie中也会生成一个cerftoken

     <form action="/login/" method="POST">
            {% csrf_token %}                                                           #会在html页面自动生成一个input框,并且包含一个随机的字符串     
            <input type="text" name="user" />
            <input type="text" name="pwd" />
            <input type="submit" value="提交" />
     </form>
    

        (2)通过ajax请求提交,访问后端

    <script src="/static/jquery-1.12.4.js"></script>
    <script src="/static/jquery.cookie.js"></script>
        <script>
         $(function(){ $.ajaxSetup({ beforeSend: function(xhr,settings){ xhr.setRequestHeader('X-CSRFtoken', $.cookie('csrftoken')); } }); $('#btn1').click(function () { $.ajax({ url: '/login/', type:"POST", data: {'user': 'root', 'pwd': '123'}, // headers: {'X-CSRFtoken': $.cookie('csrftoken')}, success:function(arg){ } }) }); }) </script>

       (3)views函数设置CSRF

    全局:
    
      中间件 django.middleware.csrf.CsrfViewMiddleware
    
    局部:
    
        @csrf_protect,为当前函数强制设置防跨站请求伪造功能,即便settings中没有设置全局中间件。
        @csrf_exempt,取消当前函数防跨站请求伪造功能,即便settings中设置了全局中间件。
    
    注:from django.views.decorators.csrf import csrf_exempt,csrf_protect
    

       (4)官网提供的CSRF的ajax提交设置

    <script src="/static/plugin/jquery/jquery-1.8.0.js"></script>
    <script src="/static/plugin/jquery/jquery.cookie.js"></script>
    <script type="text/javascript">
            var csrftoken = $.cookie('csrftoken');
      
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));      #只对于某个方式的提交添加CSRF
            }
            $.ajaxSetup({
                beforeSend: function(xhr, settings) {
                    if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
            function Do(){  
                $.ajax({
                    url:"/app01/test/",
                    data:{id:1},
                    type:'POST',
                    success:function(data){
                        console.log(data);
                    }
                });
      
            }
    </script>
    

     三,django中间件

     (1)django中间件原理:

      在django的settings.py中的MIDDLEWARE模块中写入某个类的以及类中的方法,并且在这个方法中已process_request做为请求的传递,经过每个中间件函数,最终将请求发送到django的url中,再经过url匹配views函数处理,最终将结果返回,并且返回时需要经过每个中间件的proess_response

    (2)中间件可以对所有的请求做一个统一的操作,例如:IP请求过滤,公共校验

    (3)自定义中间件

      1,在django 工程中创建任意的目录,例如middle

      2,在目录中创建.py文件,例如:m1.py

      3,m1.py中编写Python类代码

    from django.utils.deprecation import MiddlewareMixin
    class row1(MiddlewareMixin):
        def process_request(self,request):                                    #必须是process_request或者process_response函数
            print("1111")
        def process_response(self,request,response):
            print("aaaa")
            return response
    class row2(MiddlewareMixin):
        def process_request(self,request):
            print("2222")
        def process_response(self,request, response):
            print("bbbbb")
            return response
    class row3(MiddlewareMixin):
        def process_request(self,request):
            print("3333")
        def process_response(self,request, response):
            print("ccccc")
            return response
    

      4,在django的settings.py文件中添加中间件

    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',
    ]
    

       5,中间件其它方法

    process_view(self, request, view_func, view_func_args, viws_func_kwargs)  #增加一个中间件处理流程
    process_exception(self, request, exception)                               #捕捉view函数中的异常,并进行处理,返回给用户
    

     四,django 缓存

       1,配置

      (1)开发调试配置

    复制代码
    
        # 此为开始调试用,实际内部不做任何操作
        # 配置:
            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】)
                }
            }
    
    
        # 自定义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
    
    复制代码
    

        (2)内存缓存

    # 此缓存将内容保存至内存的变量中
    # 配置:
            CACHES = {
                'default': {
                    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
                    'LOCATION': 'unique-snowflake',
                }
            }
    
        # 注:其他配置同开发调试版本
    
    复制代码
    

       (3)文件缓存

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

        (4)数据库缓存

        # 此缓存将内容保存至数据库
    
        # 配置:
            CACHES = {
                'default': {
                    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
                    'LOCATION': 'my_cache_table', # 数据库表
                }
            }
    
        # 注:执行创建表命令 python manage.py createcachetable
    

         (5)memcache缓存,python-memcached模块

    # 此缓存使用python-memcached模块连接memcache 
    
        CACHES = {
            'default': {
                'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
                'LOCATION': '127.0.0.1:11211',
            }
        }
    
        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',
                    '172.19.26.242:11211',
                ]
            }
        }
    

         (6)memcache缓存(pylibmc模块)

        # 此缓存使用pylibmc模块连接memcache
        
        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',
                ]
            }
        }
    

       2,应用

        (1)某个view函数做缓存

        方式一:
            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)),
            ]
    

       (2)对某个html内容进行缓存

    {% load cache %}                                      #先进行load
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h1>{{ ctime }}</h1>
        <h1>{{ ctime }}</h1>
    
         {% cache 10 c1 %}                              #10为10秒,c1为缓存的key
            <h1>{{ ctime }}</h1>
         {% endcache %}
    </body>
    </html>
    

        (3)全站使用

    使用中间件,经过一系列的认证等操作,如果内容在缓存中存在,则使用FetchFromCacheMiddleware获取内容并返回给用户,当返回给用户之前,判断缓存中是否已经存在,如果不存在则UpdateCacheMiddleware会将缓存保存至缓存,从而实现全站缓存
    
        MIDDLEWARE = [
            'django.middleware.cache.UpdateCacheMiddleware',
            # 其他中间件...
            'django.middleware.cache.FetchFromCacheMiddleware',
        ]
    
        CACHE_MIDDLEWARE_ALIAS = ""
        CACHE_MIDDLEWARE_SECONDS = ""
        CACHE_MIDDLEWARE_KEY_PREFIX = ""
    

         3,缓存优先级,(1)全局的缓存(2)views函数定义的缓存(3)模板语言的缓存

     五,django 信号

      1,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          # 创建数据库连接时,自动触发
    

       2,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)
    

       3,不在wiews.py文件中的信号导入

      (1)编写信号.py文件

          (2)将信号.py文件导入到django app的__init__.py中,启动app就会将信号.py加载到内存中

          4,自定义信号

      (1)定义信号

    import django.dispatch
    pizza_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)
    
  • 相关阅读:
    虚基类练习 动物1
    UVa 10820
    hdu1027 Ignatius and the Princess II (全排列 &amp; STL中的神器)
    在windows下安装redmine及相关问题
    批量导出表数据到CSV文件
    轻松学习Ionic (二) 为Android项目集成Crosswalk(更新官方命令行工具)
    swift第一章
    socket编程演示样例(多线程)
    谋哥:玩App怎么赚钱(三)
    Oracle database wrc运行报错ORA-15557
  • 原文地址:https://www.cnblogs.com/system-public/p/6275824.html
Copyright © 2011-2022 走看看