第二十二章html
內容:python
session、form驗證、中間件、緩存、信號數據庫
一.sessiondjango
Django中默認支持Session,其內部提供了5種類型的Session供開發者使用:json
一、數據庫Session瀏覽器
1 Django默認支持Session,而且默認是將Session數據存儲在數據庫中,即:django_session 表中。 2 3 a. 配置 settings.py 4 5 SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默認) 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串(默認) 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑(默認) 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默認) 10 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie(默認) 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸(默認) 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默認) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時(默認) 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存(默認) 15 16 17 18 b. 使用 19 20 def index(request): 21 # 獲取、設置、刪除Session中數據 22 request.session['k1'] 23 request.session.get('k1',None) 24 request.session['k1'] = 123 25 request.session.setdefault('k1',123) # 存在則不設置 26 del request.session['k1'] 27 28 # 全部 鍵、值、鍵值對 29 request.session.keys() 30 request.session.values() 31 request.session.items() 32 request.session.iterkeys() 33 request.session.itervalues() 34 request.session.iteritems() 35 36 37 # 用戶session的隨機字符串 38 request.session.session_key 39 40 # 將全部Session失效日期小於當前日期的數據刪除 41 request.session.clear_expired() 42 43 # 檢查 用戶session的隨機字符串 在數據庫中是否 44 request.session.exists("session_key") 45 46 # 刪除當前用戶的全部Session數據 47 request.session.delete("session_key") 48 49 request.session.set_expiry(value) 50 * 若是value是個整數,session會在些秒數後失效。 51 * 若是value是個datatime或timedelta,session就會在這個時間後失效。 52 * 若是value是0,用戶關閉瀏覽器session就會失效。 53 * 若是value是None,session會依賴全局session失效策略。
二、緩存Session緩存
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 4 SESSION_CACHE_ALIAS = 'default' # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置 5 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 10 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存 15 16 17 18 b. 使用 19 20 同上
三、文件Session服務器
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 4 SESSION_FILE_PATH = None # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T 5 6 7 SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在瀏覽器上時的key,即:sessionid=隨機字符串 8 SESSION_COOKIE_PATH = "/" # Session的cookie保存的路徑 9 SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名 10 SESSION_COOKIE_SECURE = False # 是否Https傳輸cookie 11 SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http傳輸 12 SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否關閉瀏覽器使得Session過時 14 SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存 15 16 b. 使用 17 18 同上
四、緩存+數據庫Sessioncookie
1 數據庫用於作持久化,緩存用於提升效率 2 3 a. 配置 settings.py 4 5 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 6 7 b. 使用 8 9 同上
五、加密cookie Sessionsession
1 a. 配置 settings.py 2 3 SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎 4 5 b. 使用 6 7 同上
擴展:Session用戶驗證
1 def login(func): 2 def wrap(request, *args, **kwargs): 3 # 若是未登錄,跳轉到指定頁面 4 if request.path == '/test/': 5 return redirect('http://www.baidu.com') 6 return func(request, *args, **kwargs) 7 return wrap
2、form
django中的Form通常有兩種功能:
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 import re 4 from django import forms 5 from django.core.exceptions import ValidationError 6 7 8 def mobile_validate(value): 9 mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$') 10 if not mobile_re.match(value): 11 raise ValidationError('手機號碼格式錯誤') 12 13 14 class PublishForm(forms.Form): 15 16 user_type_choice = ( 17 (0, u'普通用戶'), 18 (1, u'高級用戶'), 19 ) 20 21 user_type = forms.IntegerField(widget=forms.widgets.Select(choices=user_type_choice, 22 attrs={'class': "form-control"})) 23 24 title = forms.CharField(max_length=20, 25 min_length=5, 26 error_messages={'required': u'標題不能爲空', 27 'min_length': u'標題最少爲5個字符', 28 'max_length': u'標題最多爲20個字符'}, 29 widget=forms.TextInput(attrs={'class': "form-control", 30 'placeholder': u'標題5-20個字符'})) 31 32 memo = forms.CharField(required=False, 33 max_length=256, 34 widget=forms.widgets.Textarea(attrs={'class': "form-control no-radius", 'placeholder': u'詳細描述', 'rows': 3})) 35 36 phone = forms.CharField(validators=[mobile_validate, ], 37 error_messages={'required': u'手機不能爲空'}, 38 widget=forms.TextInput(attrs={'class': "form-control", 39 'placeholder': u'手機號碼'})) 40 41 email = forms.EmailField(required=False, 42 error_messages={'required': u'郵箱不能爲空','invalid': u'郵箱格式錯誤'}, 43 widget=forms.TextInput(attrs={'class': "form-control", 'placeholder': u'郵箱'})) 44 45 Form
1 def publish(request): 2 ret = {'status': False, 'data': '', 'error': '', 'summary': ''} 3 if request.method == 'POST': 4 request_form = PublishForm(request.POST) 5 if request_form.is_valid(): 6 request_dict = request_form.clean() 7 print request_dict 8 ret['status'] = True 9 else: 10 error_msg = request_form.errors.as_json() 11 ret['error'] = json.loads(error_msg) 12 return HttpResponse(json.dumps(ret)) 13 14 View
擴展:ModelForm
在使用Model和Form時,都須要對字段進行定義並指定類型,經過ModelForm則能夠省去From中字段的定義
1 class AdminModelForm(forms.ModelForm): 2 3 class Meta: 4 model = models.Admin 5 #fields = '__all__' 6 fields = ('username', 'email') 7 8 widgets = { 9 'email' : forms.PasswordInput(attrs={'class':"alex"}), 10 }
3、緩存
因爲Django是動態網站,全部每次請求均會去數據進行相應的操做,當程序訪問量大時,耗時必然會更加明顯,最簡單解決方式是使用:緩存,緩存將 一個某個views的返回值保存至內存或者memcache中,5分鐘內再有人來訪問時,則再也不去執行view中的操做,而是直接從內存或者Redis中 以前緩存的內容拿到,並返回。
Django中提供了6種緩存方式:
一、配置
a、開發調試
1 # 此爲開始調試用,實際內部不作任何操做 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎 6 'TIMEOUT': 300, # 緩存超時時間(默認300,None表示永不過時,0表示當即過時) 7 'OPTIONS':{ 8 'MAX_ENTRIES': 300, # 最大緩存個數(默認300) 9 'CULL_FREQUENCY': 3, # 緩存到達最大個數以後,剔除緩存個數的比例,即:1/CULL_FREQUENCY(默認3) 10 }, 11 'KEY_PREFIX': '', # 緩存key的前綴(默認空) 12 'VERSION': 1, # 緩存key的版本(默認1) 13 'KEY_FUNCTION' 函數名 # 生成key的函數(默認函數會生成爲:【前綴:版本:key】) 14 } 15 } 16 17 18 # 自定義key 19 def default_key_func(key, key_prefix, version): 20 """ 21 Default function to generate keys. 22 23 Constructs the key used by all other methods. By default it prepends 24 the `key_prefix'. KEY_FUNCTION can be used to specify an alternate 25 function with custom key making behavior. 26 """ 27 return '%s:%s:%s' % (key_prefix, version, key) 28 29 def get_key_func(key_func): 30 """ 31 Function to decide which key function to use. 32 33 Defaults to ``default_key_func``. 34 """ 35 if key_func is not None: 36 if callable(key_func): 37 return key_func 38 else: 39 return import_string(key_func) 40 return default_key_func
b、內存
1 # 此緩存將內容保存至內存的變量中 2 # 配置: 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 6 'LOCATION': 'unique-snowflake', 7 } 8 } 9 10 # 注:其餘配置同開發調試版本
c、文件
1 # 此緩存將內容保存至文件 2 # 配置: 3 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', 7 'LOCATION': '/var/tmp/django_cache', 8 } 9 } 10 # 注:其餘配置同開發調試版本
d、數據庫
1 # 此緩存將內容保存至數據庫 2 3 # 配置: 4 CACHES = { 5 'default': { 6 'BACKEND': 'django.core.cache.backends.db.DatabaseCache', 7 'LOCATION': 'my_cache_table', # 數據庫表 8 } 9 } 10 11 # 注:執行建立表命令 python manage.py createcachetable
e、Memcache緩存(python-memcached模塊)
1 # 此緩存使用python-memcached模塊鏈接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 13 'LOCATION': 'unix:/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
f、Memcache緩存(pylibmc模塊)
1 # 此緩存使用pylibmc模塊鏈接memcache 2 3 CACHES = { 4 'default': { 5 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 6 'LOCATION': '127.0.0.1:11211', 7 } 8 } 9 10 CACHES = { 11 'default': { 12 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 13 'LOCATION': '/tmp/memcached.sock', 14 } 15 } 16 17 CACHES = { 18 'default': { 19 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 20 'LOCATION': [ 21 '172.19.26.240:11211', 22 '172.19.26.242:11211', 23 ] 24 } 25 }
二、應用
a. 全站使用
1 使用中間件,通過一系列的認證等操做,若是內容在緩存中存在,則使用FetchFromCacheMiddleware獲取內容並返回給用戶,當返回給用戶以前,判斷緩存中是否已經存在,若是不存在則UpdateCacheMiddleware會將緩存保存至緩存,從而實現全站緩存 2 3 MIDDLEWARE = [ 4 'django.middleware.cache.UpdateCacheMiddleware', 5 # 其餘中間件... 6 'django.middleware.cache.FetchFromCacheMiddleware', 7 ] 8 9 CACHE_MIDDLEWARE_ALIAS = "" 10 CACHE_MIDDLEWARE_SECONDS = "" 11 CACHE_MIDDLEWARE_KEY_PREFIX = ""
b. 單獨視圖緩存
方式一: 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、局部視圖使用
1 a. 引入TemplateTag 2 3 {% load cache %} 4 5 b. 使用緩存 6 7 {% cache 5000 緩存key %} 8 緩存內容 9 {% endcache %}
4、信號
Django中提供了「信號調度」,用於在框架執行操做時解耦。通俗來說,就是一些動做發生的時候,信號容許特定的發送者去提醒一些接受者。
一、Django內置信號
1 Model signals 2 pre_init # django的modal執行其構造方法前,自動觸發 3 post_init # django的modal執行其構造方法後,自動觸發 4 pre_save # django的modal對象保存前,自動觸發 5 post_save # django的modal對象保存後,自動觸發 6 pre_delete # django的modal對象刪除前,自動觸發 7 post_delete # django的modal對象刪除後,自動觸發 8 m2m_changed # django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發 9 class_prepared # 程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發 10 Management signals 11 pre_migrate # 執行migrate命令前,自動觸發 12 post_migrate # 執行migrate命令後,自動觸發 13 Request/response signals 14 request_started # 請求到來前,自動觸發 15 request_finished # 請求結束後,自動觸發 16 got_request_exception # 請求異常後,自動觸發 17 Test signals 18 setting_changed # 使用test測試修改配置文件時,自動觸發 19 template_rendered # 使用test測試渲染模板時,自動觸發 20 Database Wrappers 21 connection_created # 建立數據庫鏈接時,自動觸發
對於Django內置的信號,僅需註冊指定信號,當程序執行相應操做時,自動觸發註冊函數:
1 from django.core.signals import request_finished 2 from django.core.signals import request_started 3 from django.core.signals import got_request_exception 4 5 from django.db.models.signals import class_prepared 6 from django.db.models.signals import pre_init, post_init 7 from django.db.models.signals import pre_save, post_save 8 from django.db.models.signals import pre_delete, post_delete 9 from django.db.models.signals import m2m_changed 10 from django.db.models.signals import pre_migrate, post_migrate 11 12 from django.test.signals import setting_changed 13 from django.test.signals import template_rendered 14 15 from django.db.backends.signals import connection_created 16 17 18 def callback(sender, **kwargs): 19 print("xxoo_callback") 20 print(sender,kwargs) 21 22 xxoo.connect(callback) 23 # xxoo指上述導入的內容
1 from django.core.signals import request_finished 2 from django.dispatch import receiver 3 4 @receiver(request_finished) 5 def my_callback(sender, **kwargs): 6 print("Request finished!")
二、自定義信號
a. 定義信號
1 import django.dispatch 2 pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
b. 註冊信號
1 def callback(sender, **kwargs): 2 print("callback") 3 print(sender,kwargs) 4 5 pizza_done.connect(callback)
c. 觸發信號
from 路徑 import pizza_done pizza_done.send(sender='seven',toppings=123, size=456)
因爲內置信號的觸發者已經集成到Django中,因此其會自動調用,而對於自定義信號則須要開發者在任意位置觸發
上課筆記:
day22知識點概要 - Session - CSRF - Model操做 - Form驗證(ModelForm) - 中間件 - 緩存 - 信號內容詳細:1. Session 基於Cookie作用戶驗證時:敏感信息不適合放在cookie中 a. Session原理 Cookie是保存在用戶瀏覽器端的鍵值對 Session是保存在服務器端的鍵值對 b. Cookie和Session對比 c. Session配置(缺乏cache) d. 示例:實現兩週自動登錄 - request.session.set_expiry(60*10) - SESSION_SAVE_EVERY_REQUEST = True PS: cookie中不設置超時時間,則表示關閉瀏覽器自動清除 - session依賴於cookie - 服務器session request.session.get() request.session[x] = x request.session.clear() - 配置文件中設置默認操做(通用配置): 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過時(默認) # set_cookie('k',123) SESSION_SAVE_EVERY_REQUEST = False # 是否每次請求都保存Session,默認修改以後才保存(默認) - 引擎的配置 2. CSRF a. CSRF原理 b. 無CSRF時存在隱患 c. Form提交(CSRF) d. Ajax提交(CSRF) CSRF請求頭 X-CSRFToken 6. 中間件7. 緩存 5種配置 3種應用: 全局 視圖函數 模板8. 信號 - 內置信號 - 自定義 - 定義信號 - 出發信號 - 信號中註冊函數 3. Model操做 a. 字段類型 + 參數 b. 連表字段 + 參數 c. Meta d. SQL操做: - 基本增刪改查 - 進階操做 - 正反查詢 - 其餘操做 e. 驗證(弱)4. Form操做 完成: - 驗證用戶請求 - 生成HTML (保留上一次提交的數據) 自定義: - 類 - 字段(校驗) - 插件(生成HTML) 初始化操做: a. Form驗證用戶請求 b. Form生成HTML c. Form字段詳細(自定義字段,Model...) + 插件 d. 自定義驗證(鉤子以及__all__) e. 註冊示例: 用戶名、密碼、郵箱、手機號(RegexValidator或RegexField)、性別、愛好、城市 f. 初始化值5. ModelForm a. Model+Form功能集合 b. save c. save + save_m2m