{{ page_str|safe }}
b.後端使用mark_safe方法:css
from django.utils.safestring import mark_safe mark_safe(page_str)
分頁時須要作三件事:html
自定義分頁插件:前端
1 import math 2 from django.utils.safestring import mark_safe 3 4 5 class Page(object): 6 """自定義分頁插件""" 7 8 def __init__(self, current_page, data_count, per_page_count=10, pager_num=7): 9 self.current_page = current_page # 當前頁碼 10 self.data_count = data_count # 數據總個數 11 self.per_page_count = per_page_count # 每頁顯示幾行數據 12 self.pager_num = pager_num # 頁面總共顯示幾個頁碼 13 14 @property 15 def start(self): 16 """獲取數據起始位置""" 17 return (self.current_page - 1) * self.per_page_count 18 19 @property 20 def end(self): 21 """獲取數據終止位置""" 22 return self.current_page * self.per_page_count 23 24 @property 25 def total_count(self): 26 """獲取總頁數""" 27 return int(math.ceil(self.data_count / self.per_page_count)) 28 29 def page_str(self, base_url): 30 """獲取分頁HTML""" 31 page_list = [] # 存放html內容 32 33 if self.total_count < self.pager_num: # 若是總頁數小於要顯示的頁碼 34 start_index = 1 35 end_index = self.total_count + 1 36 else: 37 if self.current_page <= (self.pager_num + 1) / 2: 38 start_index = 1 39 end_index = self.pager_num + 1 40 else: 41 start_index = self.current_page - (self.pager_num - 1) / 2 42 end_index = self.current_page + (self.pager_num + 1) / 2 43 if (self.current_page + (self.pager_num - 1) / 2) > self.total_count: 44 end_index = self.total_count + 1 45 start_index = self.total_count - self.pager_num + 1 46 47 if self.current_page == 1: 48 prev = '<li><a href="#">«</a></li>' 49 else: 50 prev = '<li><a href="%s?p=%s">«</a></li>' % (base_url, self.current_page - 1,) 51 page_list.append(prev) 52 53 for i in range(int(start_index), int(end_index)): 54 if i == self.current_page: 55 temp = '<li class="active"><a href="%s?p=%s">%s</a></li>' % (base_url, i, i) 56 else: 57 temp = '<li><a href="%s?p=%s">%s</a></li>' % (base_url, i, i) 58 page_list.append(temp) 59 60 if self.current_page == self.total_count: 61 nex = '<li><a href="#">»</a></li>' 62 else: 63 nex = '<li><a href="%s?p=%s">»</a></li>' % (base_url, self.current_page + 1,) 64 page_list.append(nex) 65 66 jump = """ 67 <li> 68 <a style='padding: 0;'><input type='text' style='width: 50px;height: 33px;'/></a> 69 <a href="#" onclick='jumpTo(this, "%s?p=");'>GO</a> 70 </li> 71 <li style="line-height:33px;">當前第%s頁/總共%s頁 </li> 72 <script> 73 function jumpTo(ths,base){ 74 var val = ths.previousElementSibling.firstElementChild.value; 75 if(val){ 76 location.href = base + val; 77 } 78 } 79 </script> 80 """ % (base_url, self.current_page, self.total_count) 81 82 page_list.append(jump) 83 84 page_str = mark_safe("".join(page_list)) 85 86 return page_str
request.COOKIES['key'] request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None) 參數: default: 默認值 salt: 加密鹽 max_age: 後臺控制過時時間
二、設置Cookie:python
rep = HttpResponse(...) 或 rep = render(request, ...) rep.set_cookie(key,value,...) rep.set_signed_cookie(key,value,salt='加密鹽',...) 參數: key, 鍵 value='', 值 max_age=None, 超時時間 expires=None, 超時時間(IE requires expires, so set it if hasn't been already.) path='/', Cookie生效的路徑,/ 表示根路徑,特殊的:跟路徑的cookie能夠被任何url的頁面訪問 domain=None, Cookie生效的域名 secure=False, https傳輸 httponly=False 只能http協議傳輸,沒法被JavaScript獲取(不是絕對,底層抓包能夠獲取到也能夠被覆蓋)
因爲cookie保存在客戶端的電腦上,因此,JavaScript和jquery也能夠操做cookie。mysql
<script src='/static/js/jquery.cookie.js'></script> $.cookie("list_pager_num", 30,{ path: '/' });
Django默認支持Session,而且默認是將Session數據存儲在數據庫中,即:django_session 表中。 配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默認)
b、緩存Sessionjquery
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的緩存別名(默認內存緩存,也能夠是memcache),此處別名依賴緩存的設置
c、文件Sessionweb
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 # 緩存文件路徑,若是爲None,則使用tempfile模塊獲取一個臨時地址tempfile.gettempdir() # 如:/var/folders/d3/j9tj0gz93dg06bmwxmhh6_xm0000gn/T SESSION_FILE_PATH = None
d、緩存加數據庫Sessionajax
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
e、加密Cookie Sessionsql
配置 settings.py SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
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,默認修改以後才保存(默認)
使用:數據庫
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失效策略。
veiw中設置返回值: return render_to_response('Account/Login.html',data,context_instance=RequestContext(request)) 或者 return render(request, 'xxx.html', data) html中設置Token: {% csrf_token %}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <form id="f1" action="/login/" method="POST"> {% csrf_token %} <input type="text" name="username" placeholder="username"> <input type="password" name="password" placeholder="password"> <input type="checkbox" name="rmb" value="1"> 10秒免登陸 <input type="submit" value="confirm"> <input type="button" value="ok"> </form> <script src="/static/jquery-1.12.4.js"></script> <script src="/static/jquery.cookie.js"></script> <script> $(function () {
$(":button").click(function () { $.ajax({ url:"/login/", type:"POST", data:$("#f1").serialize(), dataType:"JSON", traditional:true, success:function (arg) { } }) }) }) </script> </body> </html>
以上方法的返回值能夠是None和HttpResonse對象,若是是None,則繼續按照django定義的規則向下執行,若是是HttpResonse對象,則直接將該對象返回給用戶。
from django.utils.deprecation import MiddlewareMixin from django.template.exceptions import TemplateDoesNotExist class MyMiddleWare(MiddlewareMixin): def process_request(self, request): print('1') def process_view(self, request, view_func, view_func_args, view_func_kwargs): print('2') def process_response(self, request, response): print('3') return response # 必須將內容返回給用戶 def process_exception(self, request, exception): """只有出現異常時纔會執行""" if isinstance(exception, ValueError): return HttpResponse('出現異常》。。') elif isinstance(exception, TemplateDoesNotExist): print(request.path_info) return render(request, "404.html") def process_template_response(self, request, response): """若是Views中的函數返回的對象中,具備render方法纔會執行""" print('-----------------------') 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.MyMiddleWare' ]
Django中提供了6種緩存方式:
# 此爲開始調試用,實際內部不作任何操做 # 配置: 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模塊)
# 此緩存使用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 %}
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 # 程序啓動時,檢測已註冊的app中的modal類,對於每個類,自動觸發 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 # 執行migrate命令先後 from django.test.signals import setting_changed # 使用test測試修改配置文件時 from django.test.signals import template_rendered # 使用test測試渲染模板時 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!")
ps:須要先將本身寫的信號文件初始化到django工程中,和使用pymysql模塊同樣,以下所示:
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)
ps:因爲內置信號的觸發者已經集成到Django中,因此其會自動調用,而對於自定義信號則須要開發者在任意位置觸發。