拾伍 ● Ajax技術
一 ● Ajax定義
Ajax: 異步的 JavaScript 和 XML (Asynchronous+Javascript+XML) 通過Ajax, 我們可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新(重新加載整個網頁是: 雕版印刷, 對網頁的某個部分進行更新: 活字印刷) |
※ 異步: 向服務器發送請求的時候,我們不必等待結果,而是可以同時做其他的事情,等到有了結果我們可以再來處理這個事 |
二 ● 常見Ajax技術
1 ● $.post()、$.get()、$.load()是一些簡單Ajax方法(用得較少)
<html> <head> <script type="text/javascript" src="/jquery/jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $("#b01").click(function () { $('#myDiv').load('/jquery/test1.txt'); }); }); </script> </head> <body>
<div id="myDiv"><h2>通過 AJAX 改變文本</h2></div> <button id="b01" type="button">改變內容</button>
</body> </html> |
2 ● jQuery.ajax(), 即$.ajax(), 能處理復雜的邏輯
一般使用格式 $("#login_btn").on("click", function () { $.ajax({ url: "/foo/", type: 'POST', data: 鍵值對(data是引用數據類型), success: function(data){}, dataType: dataType }); }); |
$.ajax()的參數是一個字典, 它的鍵包括: url→必需,(默認為當前頁地址)指向要操作的路徑 type→可選, 請求方式("POST", "GET") data→可選, 鍵值對(data是引用數據類型), 連同請求發送到服務器。 success→可選, 請求成功時執行的回調函數。 dataType→可選, 規定預期的服務器響應的數據類型。若未指定, 則智能判斷(xml、json、script 或 html)。 |
※ 如果要處理 $.ajax() 得到的數據,則需要使用回調函數:beforeSend、error、dataFilter、success、complete。 |
※ jQuery.ajax()的參數列表
參數名 |
類型 |
描述 |
url |
String |
(默認: 當前頁地址) 發送請求的地址。 |
type |
String |
(默認: "GET") 請求方式 ("POST" 或 "GET"),默認為 "GET"。注意:其它HTTP 請求方法,如 PUT 和 DELETE 也可以使用,但僅部分瀏覽器支持。 |
timeout |
Number |
設置請求超時時間(毫秒)。此設置將覆蓋全局設置。 |
async |
Boolean |
(默認: true) 默認設置下,所有請求均為異步請求。如果需要發送同步請求,請將此選項設置為 false。注意,同步請求將鎖住瀏覽器,用戶其它操作必須等待請求完成才可以執行。 |
beforeSend |
Function |
發送請求前可修改 XMLHttpRequest 對象的函數,如添加自定義 HTTP頭。XMLHttpRequest 對象是唯一的參數。 function (XMLHttpRequest) { this; // the options for this ajax request } |
cache |
Boolean |
(默認: true) jQuery 1.2 新功能,設置為 false 將不會從瀏覽器緩存中加載請求信息。 |
complete |
Function |
請求完成后回調函數 (請求成功或失敗時均調用)。參數:XMLHttpRequest 對象,成功信息字符串。 function (XMLHttpRequest, textStatus) { this; // the options for this ajax request } |
contentType |
String |
(默認: "application/x-www-form-urlencoded") 發送信息至服務器時內容編碼類型。默認值適合大多數應用場合。 ※ from的enctype屬性的默認值也是application/x-www-form-urlencoded |
data |
Object, String |
發送到服務器的數據。將自動轉換為請求字符串格式。GET 請求中將附加在 URL 后。查看 processData 選項說明以禁止此自動轉換。必須為Key/Value 格式。如果為數組,jQuery 將自動為不同值對應同一個名稱。如 {foo:["bar1", "bar2"]} 轉換為 '&foo=bar1&foo=bar2'。 |
dataType |
String |
預期服務器返回的數據類型。如果不指定,jQuery 將自動根據 HTTP 包MIME 信息返回 responseXML 或 responseText,並作為回調函數參數傳遞,可用值: "xml": 返回 XML 文檔,可用 jQuery 處理。 "html": 返回純文本 HTML 信息;包含 script 元素。 "script": 返回純文本 JavaScript 代碼。不會自動緩存結果。 "json": 返回 JSON 數據。 "jsonp": JSONP 格式。使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數。 |
error |
Function |
(默認: 自動判斷 (xml 或 html)) 請求失敗時將調用此方法。這個方法有三個參數:XMLHttpRequest 對象,錯誤信息,(可能)捕獲的錯誤對象。 function (XMLHttpRequest, textStatus, errorThrown) { // 通常情況下textStatus和errorThown只有其中一個有值 this; // the options for this ajax request } |
global |
Boolean |
(默認: true) 是否觸發全局 AJAX 事件。設置為 false 將不會觸發全局 AJAX事件,如 ajaxStart 或 ajaxStop 。可用於控制不同的Ajax事件 |
ifModified |
Boolean |
(默認: false) 僅在服務器數據改變時獲取新數據。使用 HTTP 包 Last-Modified 頭信息判斷。 |
processData |
Boolean |
(默認: true) 默認情況下,發送的數據將被轉換為對象(技術上講並非字符串) 以配合默認內容類型 "application/x-www-form-urlencoded"。如果要發送 DOM 樹信息或其它不希望轉換的信息,請設置為 false。 |
success |
Function |
請求成功后回調函數。這個方法有兩個參數:服務器返回數據,返回狀態 function (data, textStatus) { // data could be xmlDoc, jsonObj, html, text, etc... this; // the options for this ajax request } |
3 ● jQuery的serialize() 方法
語法: $(selector).serialize() serialize() 方法通過序列化表單值創建 URL 編碼的文本字符串。 您可以選擇一個或多個表單元素(如輸入和/或文本區),或表單元素本身。 序列化的值可在生成 AJAX 請求時, 用於 URL 查詢字符串中。 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>菜鳥教程(runoob.com)</title> <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js"> </script> <script> $(document).ready(function () { $("button").click(function () { $("div").text($("form").serialize()); }); }); </script> </head> <body>
<form action=""> 第一個名稱: <input type="text" name="FirstName" value="Mickey"/><br> 最后一個名稱: <input type="text" name="LastName" value="Mouse"/><br> </form> <button>序列化表單值</button> <div></div>
</body> </html>
效果: |
序列化
● Django支持的序列化格式
Django支持的序列化格式包括json, xml和yaml, 我們只關注json的django序列化格式 |
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式,主要用於傳送數據。 |
● Django的serializers.serialize() & python的json.dumps()
對於Django的Queryset<Queryset [object,object,object]>, 不能使用python的json方法序列化,而要用到django的 serializers |
情況1: 使用serializers.serialize from django.core import serializers
ret = models.BookType.objects.all() data = serializers.serialize("json", ret)
#serialize()的參數是: # 序列化目標格式, # 序列化的QuerySet對象 (事實上,第二個參數可以是任何可迭代的Django Model實例,但它很多情況下就是一個QuerySet). |
情況2: 使用json.dumps()
|
拾陸 ● Django的表單系統: 主要分兩種
一● 基於django.forms.Form
定義形式 from django import forms class FormName(forms.Form): field1 = forms.XXField(...) # model字段是field1 = models.XXField(...) field2 = forms.XXField(...)
表單字段的參數包括(不一定都有, 用逗號分隔參數) ① max_length這種字段固有的參數 ② 部件(widget)對象 ※ 字段參數負責"校驗邏輯",而部件對象負責" 顯示邏輯" #form.py from django import forms
class CommentForm(forms.Form): name = forms.CharField() url = forms.URLField() comment = forms.CharField(widget=forms.Textarea()) # Textarea后的括號可以省略 # Widget (部件)是Django 對HTML 輸入元素的表示。(A widget is Django's representation of an HTML input element.) # 這里的 comment 會變成 Textarea,而不是 CharField
# 如果想讓Widget 具有一些特殊的CSS 類, 可以這樣設置: class CommentForm(forms.Form): name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'})) url = forms.URLField() comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'})) |
title = forms.CharField(max_length=20, min_length=5, error_messages={'required': '標題不能為空', 'min_length': '標題最少為5個字符', 'max_length': '標題最多為20個字符'}, widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': '標題5-20個字符'})) |
●細節知識
Form 的對象具有一個is_valid() 方法,它為所有的字段運行驗證的程序。 當調用這個方法時,如果所有的字段都包含合法的數據,它將: ① 返回True ② 將表單的數據放到cleaned_data屬性中。 |
其它Form對象的API: http://www.lxway.com/496695522.htm |
二● 基於django.forms.ModelForm
※ ModelForm 能允許我們通過一個 Model, 直接創建一個和該Model的字段一一對應的表單,大大方便了表單操作: #models.py class ExamInfo(models.Model): field1 = models.XXField(...) # 表單字段是field1 = forms.XXField(...) field2 = models.XXField(...)
#form.py #定義ExamInfo的Form,Form的名字為模型名+Form from django.forms import ModelForm from .models import ExamInfo class ExamInfoForm(ModelForm): class Meta: model = ExamInfo fields = '__all__' # fields = ('field1','field2') #只顯示model中指定的字段 |
● ※ form組件的主要功能
① 生成HTML標簽 ② 驗證用戶數據(顯示錯誤信息)----對用戶提交的內容進行驗證(from表單/Ajax) ③ 提交、保留上次提交的數據 ④ 初始化頁面顯示內容 |
● ※ 鈎子(hook)(對於django來說)
局部鈎子:校驗單個字段,例如:用戶名最短5個字符,最長12個字符;密碼必須大於8位,驗證碼必須正確 全局鈎子:校驗多個字段,例如:密碼和重復密碼必須一致
※ 對於MFC編程來說,消息鈎子分為局部鈎子和全局鈎子。 局部鈎子將僅攔截某一進程的指定消息, 全局鈎子將攔截系統中所有進程的指定消息。 |
拾柒 ● 跨站請求偽造(csrf/xsrf, Cross-site request forgery)
一 ● csrf定義
Django具有防止跨站請求偽造的功能,有全局和局部之分 --全局防止跨站請求偽造通過中間件 django.middleware.csrf.CsrfViewMiddleware 來完成 --局部防止跨站請求偽造通過@csrf_protect和@csrf_exempt裝飾器來實現 ※ from django.views.decorators.csrf import csrf_protect, csrf_exempt ※ @csrf_protect,為當前函數強制設置防跨站請求偽造功能,即便settings中沒有設置全局中間件。 ※ @csrf_exempt,取消當前函數防跨站請求偽造功能,即便settings中設置了全局中間件。 |
二 ● csrf案例
用戶訪問www.mybank.com網站, 登錄並且未退出, 用戶同時訪問了一個黑客網站, 黑客網站發給客戶的html代碼中帶有上面的代碼(一段假裝生成一個圖片元素的html代碼, 是get方式的數據傳遞), 因而訪問了src對應的可實現轉賬的代碼(此時cookie未失效), 因此, 一段服務端發給瀏覽器的csrf_token可用來驗證某段代碼是用戶的瀏覽器發送的代碼, 而不是其它服務器發送的. |
三 ● csrf的應用
※ 詳見: https://www.cnblogs.com/zhaof/p/6281482.html
1 ● 普通表單
|
這樣當你查看頁面源碼的時候,可以看到form中有一個input是隱藏的 總結原理:當用戶訪問login頁面的時候,會生成一個csrf的隨機字符串,並且cookie中也存放了這個隨機字符串(如下圖),當用戶再次提交數據的時候會帶着這個隨機字符串提交,如果沒有這個隨機字符串則無法提交成功 |
2 ● Ajax
對於傳統的form,可以通過表單的方式將token再次(體會這個再次)發送到服務端,而對於ajax的話,使用如下方式。 |
1, csrf在ajax提交的時候是通過請求頭(headers)傳遞的給后台的 2, csrf在前端的key為:X-CSRFtoken,到后端的時候django會自動添加HTTP_,並且最后為HTTP_X_CSRFtoken 3, csrf在form中提交的時需要在前端form中添加{%csrftoken%} |
|
|
拾捌 ● WSGI
一 ● WSGI定義
※ CGI(Common Gateway Interface)是通用網關接口,而WSGI就是Python的CGI包裝,相對於Fastcgi是PHP的CGI包裝, 它規定了Web服務器調用其他可執行程序(CGI程序)的接口協議標准。 |
(1) WSGI(Web Server Gateway Interface, Web服務器網關接口)是一種規范, 是將Python服務器端程序連接到Web服務器的通用協議,它實現了Web服務器和Web應用程序之間的解耦(decoupling)。
(2) WSGI接口規范的目的就是規范Web服務器與Web應用之間的交互,在協議之間進行轉換(WSGI就是Web就是一個網關(Gateway),而網關的作用就是在協議之間進行轉換。)
(3) WSGI將Web組件分成三類:Web服務器(WSGI Server)、Web中間件(WSGI Middleware)與Web應用程序(WSGI Application)。 --服務器:指的是實現了調用應用(call application)的部分。 --中間件:處於服務器和應用兩側,起粘合作用,具體包括:請求處理、environ, 即環境變量的處理。 --應用:指的是可以被調用的一個對象,一般指的是包含一個__call__方法(實例可以當作函數一般調用)的對象。
python標准庫提供的獨立WSGI服務器(WSGI server)稱為wsgiref(模塊)。 |
二 ● 注意
※ environ是Python內置的dict對象,它是系統的環境變量; ※ 通過import os; os.environ獲取所有的環境變量; ※ 查看環境變量: os.environ.get('path')可以獲取path這個環境變量被賦值的路徑 ※ 設置環境變量: os.environ["PATH"] = os.environ["PATH"]+';' + "要增加的路徑" |
三 ● WSGI的角色
WSGI的接口分為兩個: 一個是它與Web服務器的接口,另一個是它與服務器端程序的接口。 ① WSGI Server與Web服務器的接口包括uwsgi、fast cgi等 (我們無須詳細學習) ② 服務器端的開發者需要關注的是WSGI與服務器端程序的接口。 |
※ Django、CherryPy 都自帶符合WSGI規范的 WSGI server, ※ 而有些 WSGI 下的框架比如 pylons、bfg 等, 自己不實現 WSGI server, 而是使用 paste 作為 WSGI server, paste 是流行的 WSGI server, 帶有很多中間件。 |
四 ● Django內置的服務器
Django 內部自帶了一個方便本地測試的小服務器, 所以在剛開始學習 Django 的時候並不需搭建 apache 或者 nginx 服務器.
Django 自帶的服務器基於 python wsgiref 模塊實現的, 其百分之七八十的代碼都是 wsgiref 中的代碼, 只重寫了一部分. 具體來說, Django 內置服務器基於 django.core.servers 和 django.core.handlers這兩個類共同實現. |
拾玖 ● 中間件(MIDDLEWARE )
一 ● 中間件的介紹
在django中,中間件其實就是一個類; 在settings.py中,MIDDLEWARE 列表的每一個元素就是一個中間件:
在http請求到達視圖函數之前和視圖函數return之后,Django會根據自己的規則在合適的時機執行中間件中相應的方法。
注意: 如果在其中一個中間件里 request方法里 return了值,就會執行當前中間件的response方法,返回給用戶然后報錯, 並且不會再執行下一個中間件。
Django會先按順序執行各個中間件的request方法, 然后執行視圖函數, 然后反序執行各個中間件的response方法.例如: |
二 ● 自定義中間件的步驟
|
|
結果: 為啥報錯了呢?
因為自定義的中間件response方法沒有return結果交給下一個中間件,導致http請求中斷了!!!
注意: 自定義的中間件request 方法不要return結果, 否則, 中間件不再會往下執行,導致 http請求到達不了視圖層.
|
三 ● 中間件中可以定義5個方法,分別是:
process_request(self,request) process_view(self, request, callback, callback_args, callback_kwargs) process_template_response(self,request,response) process_exception(self, request, exception) process_response(self, request, response |
有關自定義中間件, 參見: https://www.cnblogs.com/huchong/p/7819296.html |
貳拾 ● Django的信號
一 ● 信號的定義
Django中提供了"信號調度",用於在框架執行操作時解耦. 一些動作發生的時候,系統會根據信號定義的函數執行相應的操作. (例如下面的: 創建數據庫記錄時, 觸發pre_save和post_save信號) 對於Django內置的信號,僅需注冊指定信號,當程序執行相應操作時,系統會自動觸發注冊函數 |
二 ● 信號的案例
※ 創建數據庫記錄時, 觸發pre_save和post_save信號 |
# models.py
|
#
|
#
|
#
|
有關自定義信號
|
貳拾壹 ● Django的緩存
一 ● 緩存的定義
緩存,緩存將一個某個views的返回值保存至內存或者memcache中,之后再有人來訪問時,則不再去執行view中的操作,而是直接從內存或者Redis中之前緩存的內容拿到,並返回。 |
Django settings 中 cache 默認為 { 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', } } 也就是默認利用本地的內存來當緩存,速度很快,當然可能出來內存不夠用的情況。 |
二 ● Django中提供緩存方式
※ 下面的緩存方式都需要在setting.py里面配置: - 開發調試 - 本地內存(默認的緩存方式) - 文件 - 數據庫 - Memcache緩存(python-memcached模塊)----memcache是一套分布式的高速緩存系統 - Memcache緩存(pylibmc模塊) - Redis緩存 |
詳見: https://code.ziqiangxuetang.com/django/django-cache.html http://www.cnblogs.com/haiyan123/p/8424231.html |
貳拾貳 ● admin
django amdin是django提供的一個后台管理頁面,改管理頁面提供完善的html和css,使得你在通過Model創建完數據庫表之后,就可以對數據進行增刪改查. |
我們學習和使用更加完善的xadmin, 下面只介紹admin的簡單用法. |
● admin的一般使用步驟
① 在項目名/項目名/urls.py配置url url(r'^admin/', include(admin.site.urls))
② 注冊medel類到admin: 在應用名/admin.py里面把我們當前應用models.py里面的User 這個model注冊進去,如下。 from django.contrib import admin from .models import User
admin.site.register(User) # 通過admin.site.register()函數逐個聲明要管理的模型類. # 再如: 假設有Book, MyAdmin, Publish, Author五個模型類: admin.site.register(Book,MyAdmin) # 將Author模塊和管理類綁定在一起,注冊到后台管理 admin.site.register(Publish) admin.site.register(Author)
通過python manage.py runserver命令啟動項目,然后http://127.0.0.1:8000/admin訪問,會自動跳轉到它的主頁,如圖所示:
③ 通過"python manage.py createsuperuser"命令創建超級用戶,例如: python manage.py createsuperuser Username: admin Email address: Password: Password (again): Superuser created successfully.
假如我創建了一個用戶名:admin 密碼:admin123的用戶,我們就可以登錄進django admin后台管理系統了,登錄成功如下所示,我們可以通過右側的 "add" 添加用戶: 我們操作admin和我們操作數據庫是一樣的,例如上面的Users對應的就是sqlite數據庫中的user表,也就是說,如果要求不高的話后台都不需要我們開發了! |
貳拾叄 ● 設置404頁面和500頁面
1, 在blog/templates/user下面添加一個404.html和一個500.html頁面,代碼任意,
2, 配置setting.py文件,如下: ※ 當DEBUG=True的時候, django的runserver是自動使用StaticFilesHandler來serve 靜態文件的, 當DEBUG=False的時候, django就不處理靜態文件, 交由其它的靜態服務器來處理.
3, 在主urls.py(settings.py文件下面)添加如下配置: 前面的代碼是固定的,后面代碼的意思是在blog模塊下的views.py中處理這兩個404和500錯誤。
4, 在views.py中添加page_not_found和page_error這兩個方法,用於頁面跳轉,如下:
|
貳拾肆 ● 富文本編輯器
常用富文本編輯器 |
Kindeditor 參考: http://www.cnblogs.com/wupeiqi/articles/6307554.html
DjangoUeditor3 參考: http://www.cnblogs.com/adc8868/p/7580705.html
Tinymce 參考: http://blog.csdn.net/u010505059/article/details/78650742 |
貳拾伍 ● REST & RESTful API
REST, Representational State Transfer,"表現層狀態轉化", 全稱是 Resource Representational State Transfer, 即"資源在網絡中以某種表現形式進行狀態轉移" ※ Resource:資源,即數據(網絡的核心,例如newsfeed,friends等); Representational:某種表現形式,例如JSON,XML,JPEG等; State Transfer:狀態變化, 通過GET,POST等HTTP動詞實現。 |
RESTful API: 符合REST架構設計的API, HTTP協議就是屬於REST架構的設計模式, 例如: 無狀態,請求-響應機制. RESTful API要求增刪查改都是一個地址,具體靠HTTP請求頭部信息判斷, HTTP請求頭包括Content-Type等信息. |
※ REST是所有Web應用都應該遵守的架構設計指導原則。當然,REST並不是法律,違反了REST的指導原則,仍然能夠實現應用的功能。但是違反了REST的指導原則,會付出很多代價,特別是對於大流量的網站而言 |
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。