django的cookie和session以及內置信號、緩存


cookie和session

cookie和session的作用:

cookie和session都記錄了客戶端的某種狀態,用來跟蹤用戶訪問網站的整個回話。兩者最大的區別是cookie的信息是存放在瀏覽器客戶端的,而session是存放在服務器端的

cookie的基本操作

  • cookie增刪改查操作
1、設置Cookies 
 response.set_cookie("cookie_key","value")
2、獲取Cookies
 value = request.COOKIES["cookie_key"]
3、刪除Cookies
 response.delete_cookie("cookie_key",path="/",domain=name)
4、檢測Cookies
 if "cookie_name" is request.COOKIES :
5、rep.set_signed_cookie(key,value,salt='加密鹽',...)
    參數:
        key,              鍵
        value='',         值
        max_age=None,     超時時間,表示多少秒數之后失效
        expires=None,     超時時間,表示失效的時間點。支持datetime 和 time.time
        path='/',         Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie可以被任何url的頁面訪問
        domain=None,      Cookie生效的域名
        secure=False,     https傳輸
        httponly=False    只能http協議傳輸,無法被JavaScript獲取(不是絕對,底層抓包可以獲取到也可以被覆蓋)

由於cookie保存在客戶端的電腦上,所以,JavaScript和jquery也可以操作cookie。

<script src='/static/js/jquery.cookie.js'></script>
$.cookie("list_pager_num", 30,{ path: '/' });

 

  • 基於cookie實現用戶回話判斷 主頁index.html:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <h1>歡迎:{{ user }}登錄</h1>
</body>
</html>

 

登錄頁login.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form action="/login/"  method="POST">
        <input type="text" name="user">
        <input type="text" name="pwd">
        <input type="submit" value="提交" />
    </form>
</body>
</html>

 

url設置:

urlpatterns = [
    url(r'^log/',views.login),
    url(r'^index/',views.index),
    ]

 

views設置

from django.shortcuts import render,redirect
from django.shortcuts import HttpResponse
def login(request):
    if request.method == 'POST':
        u = request.POST.get('user')
        p = request.POST.get('pwd')
        if u == 'alex' and p == '123':
            red = redirect('/index/')  #登錄成功,則重定向到index
            red.set_cookie('username', u) #將用戶名插入cookie
            return red
        else:
            return render(request, 'login.html') 
    else:
        return render(request, 'login.html')

def index(request):
    user = request.COOKIES.get('username') #從cookie中取值
    if user:
        return render(request, 'index.html', {'user':user})
    else:
        return redirect('/log/')

 

運行django之后,訪問index,會自動跳轉到login頁面,輸入賬戶密碼之后,自動跳轉到index,並從cookie中取出username,打印出來

session的基本操作

Django中默認支持Session,其內部提供了5種類型的Session供開發者使用:

  • 數據庫(默認)
  • 緩存
  • 文件
  • 緩存+數據庫
  • 加密cookie

數據庫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")

 

緩存session

 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,默認修改之后才保存

 



文件session

配置 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. 使用
 
    同上

 

緩存+數據庫Session

數據庫用於做持久化,緩存用於提高效率
 
a. 配置 settings.py
 
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
 
b. 使用
 
    同上

 

加密cookie Session

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

 

使用session實現用戶會話判斷

views設置

def session_login(request):
    if request.method == 'POST':
        user = request.POST.get('user')
        pwd = request.POST.get('pwd')
        if user == 'fuzj' and pwd == '123':
            request.session['user'] = user
            return redirect('/session_index/')

    return render(request,'session_login.html')

@auth
def session_index(request):
    user = request.session.get('user',None)
    return render(request,'index.html',{'user':user})

def session_logout(request):
    del request.session['user']
    return redirect('/session_login/')

 

補充session的操作

request.session['k1']:獲取session,如果沒有會報錯

request.session.get('k1',None):獲取session,如果沒有會返回None

request.session['k1'] = 123:設置session,如果k1存在就覆蓋

request.session.setdefault('k1',123):設置session,如果存在則不設置

del request.session["k1"] :只刪除k1,隨機字符串和其他session值還存在

request.session.session_key:當前用戶隨機字符串

 

緩存

由於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】)
            }
        }


    # 自定義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',
            }
        }

    # 注:其他配置同開發調試版本

 

  • 文件
# 此緩存將內容保存至文件
    # 配置:

        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模塊)
# 此緩存使用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',
            ]
        }
    }

 

  • memcache
# 此緩存使用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',
            ]
        }
    }

 

應用

  • 全站使用
使用中間件,經過一系列的認證等操作,如果內容在緩存中存在,則使用FetchFromCacheMiddleware獲取內容並返回給用戶,當返回給用戶之前,判斷緩存中是否已經存在,如果不存在則UpdateCacheMiddleware會將緩存保存至緩存,從而實現全站緩存
  MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中間件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

    CACHE_MIDDLEWARE_ALIAS = ""
    CACHE_MIDDLEWARE_SECONDS = ""
    CACHE_MIDDLEWARE_KEY_PREFIX = ""

 

  • 單獨視圖緩存
方式一:
        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)),
        ]

 

  • 局部視圖緩存
a. 引入TemplateTag

        {% load cache %}

b. 使用緩存

        {% cache 5000 緩存key %}
            緩存內容
        {% endcache %}

 

參考L:https://docs.djangoproject.com/en/1.9/topics/cache/

信號

Django中提供了“信號調度”,用於在框架執行操作時解耦。通俗來講,就是一些動作發生的時候,信號允許特定的發送者去提醒一些接受者。

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_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

 

django自定義信號

  • 定義信號
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

 

  • 注冊信號
def callback(sender, **kwargs):
    print("callback")
    print(sender,kwargs)
 
pizza_done.connect(callback)

 

  • 觸發信號
from 路徑 import pizza_done
 
pizza_done.send(sender='seven',toppings=123, size=456)

 

由於內置信號的觸發者已經集成到Django中,所以其會自動調用,而對於自定義信號則需要開發者在任意位置觸發。

參考:https://docs.djangoproject.com/en/dev/topics/signals/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM