一、Django之ModelForm組件
ModelForm
a. class Meta:
model, # 對應Model的
fields=None, # 字段
exclude=None, # 排除字段
labels=None, # 提示信息
help_texts=None, # 幫助提示信息
widgets=None, # 自定義插件
error_messages=None, # 自定義錯誤信息(整體錯誤信息from django.core.exceptions import NON_FIELD_ERRORS)
field_classes=None # 自定義字段類 (也可以自定義字段)
localized_fields=('birth_date',) # 本地化,如:根據不同時區顯示數據
如:
數據庫中
2016-12-27 04:10:57
setting中的配置
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = True
則顯示:
2016-12-27 12:10:57
b. 驗證執行過程
is_valid -> full_clean -> 鈎子 -> 整體錯誤
c. 字典字段驗證
def clean_字段名(self):
# 可以拋出異常
# from django.core.exceptions import ValidationError
return "新值"
d. 用於驗證
model_form_obj = XXOOModelForm()
model_form_obj.is_valid()
model_form_obj.errors.as_json()
model_form_obj.clean()
model_form_obj.cleaned_data
e. 用於創建
model_form_obj = XXOOModelForm(request.POST)
#### 頁面顯示,並提交 #####
# 默認保存多對多
obj = form.save(commit=True)
# 不做任何操作,內部定義 save_m2m(用於保存多對多)
obj = form.save(commit=False)
obj.save() # 保存單表信息
obj.save_m2m() # 保存關聯多對多信息
f. 用於更新和初始化
obj = model.tb.objects.get(id=1)
model_form_obj = XXOOModelForm(request.POST,instance=obj)
...
PS: 單純初始化
model_form_obj = XXOOModelForm(initial={...})
二、Ajax
對於WEB應用程序:用戶瀏覽器發送請求,服務器接收並處理請求,然后返回結果,往往返回就是字符串(HTML),瀏覽器將字符串(HTML)渲染並顯示瀏覽器上。
1、傳統的Web應用
一個簡單操作需要重新加載全局數據
2、AJAX
AJAX,Asynchronous JavaScript and XML (異步的JavaScript和XML),一種創建交互式網頁應用的網頁開發技術方案。
異步的JavaScript:
- 異步的JavaScript:
使用 【JavaScript語言】 以及 相關【瀏覽器提供類庫】 的功能向服務端發送請求,當服務端處理完請求之后,【自動執行某個JavaScript的回調函數】。
PS:以上請求和響應的整個過程是【偷偷】進行的,頁面上無任何感知。
- XML
XML是一種標記語言,是Ajax在和后台交互時傳輸數據的格式之一
利用AJAX可以做:
- 注冊時,輸入用戶名自動檢測用戶是否已經存在。
- 登陸時,提示用戶名密碼錯誤
- 刪除數據行時,將行ID發送到后台,后台在數據庫中刪除,數據庫刪除成功后,在頁面DOM中將數據行也刪除。(博客園)
“偽”AJAX
由於HTML標簽的iframe標簽具有局部加載內容的特性,所以可以使用其來偽造Ajax請求。
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div>
<p>請輸入要加載的地址:<span id="currentTime"></span></p>
<p>
<input id="url" type="text" />
<input type="button" value="刷新" onclick="LoadPage();">
</p>
</div>
<div>
<h3>加載頁面位置:</h3>
<iframe id="iframePosition" style="width: 100%;height: 500px;"></iframe>
</div>
<script type="text/javascript">
window.onload= function(){
var myDate = new Date();
document.getElementById('currentTime').innerText = myDate.getTime();
};
function LoadPage(){
var targetUrl = document.getElementById('url').value;
document.getElementById("iframePosition").src = targetUrl;
}
</script>
</body>
</html>
原生AJAX
Ajax主要就是使用 【XmlHttpRequest】對象來完成請求的操作,該對象在主流瀏覽器中均存在(除早起的IE),Ajax首次出現IE5.5中存在(ActiveX控件)。
1、XmlHttpRequest對象介紹
XmlHttpRequest對象的主要方法:
a. void open(String method,String url,Boolen async)
用於創建請求
參數:
method: 請求方式(字符串類型),如:POST、GET、DELETE...
url: 要請求的地址(字符串類型)
async: 是否異步(布爾類型)
b. void send(String body)
用於發送請求
參數:
body: 要發送的數據(字符串類型)
c. void setRequestHeader(String header,String value)
用於設置請求頭
參數:
header: 請求頭的key(字符串類型)
vlaue: 請求頭的value(字符串類型)
d. String getAllResponseHeaders()
獲取所有響應頭
返回值:
響應頭數據(字符串類型)
e. String getResponseHeader(String header)
獲取響應頭中指定header的值
參數:
header: 響應頭的key(字符串類型)
返回值:
響應頭中指定的header對應的值
f. void abort()
終止請求
XmlHttpRequest對象的主要屬性:
a. Number readyState
狀態值(整數)
詳細:
0-未初始化,尚未調用open()方法;
1-啟動,調用了open()方法,未調用send()方法;
2-發送,已經調用了send()方法,未接收到響應;
3-接收,已經接收到部分響應數據;
4-完成,已經接收到全部響應數據;
b. Function onreadystatechange
當readyState的值改變時自動觸發執行其對應的函數(回調函數)
c. String responseText
服務器返回的數據(字符串類型)
d. XmlDocument responseXML
服務器返回的數據(Xml對象)
e. Number states
狀態碼(整數),如:200、404...
f. String statesText
狀態文本(字符串),如:OK、NotFound...
2、跨瀏覽器支持
- XmlHttpRequest:IE7+, Firefox, Chrome, Opera, etc.
- ActiveXObject("Microsoft.XMLHTTP"):IE6, IE5
基於原生AJAX - Demo:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1>XMLHttpRequest - Ajax請求</h1>
<input type="button" onclick="XmlGetRequest();" value="Get發送請求" />
<input type="button" onclick="XmlPostRequest();" value="Post發送請求" />
<script src="/statics/jquery-1.12.4.js"></script>
<script type="text/javascript">
function GetXHR(){
var xhr = null;
if(XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhr;
}
function XhrPostRequest(){
var xhr = GetXHR();
// 定義回調函數
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已經接收到全部響應數據,執行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定連接方式和地址----文件方式
xhr.open('POST', "/test/", true);
// 設置請求頭
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
// 發送請求
xhr.send('n1=1;n2=2;');
}
function XhrGetRequest(){
var xhr = GetXHR();
// 定義回調函數
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
// 已經接收到全部響應數據,執行以下操作
var data = xhr.responseText;
console.log(data);
}
};
// 指定連接方式和地址----文件方式
xhr.open('get', "/test/", true);
// 發送請求
xhr.send();
}
</script>
</body>
</html>
jQuery Ajax
jQuery其實就是一個JavaScript的類庫,其將復雜的功能做了上層封裝,使得開發者可以在其基礎上寫更少的代碼實現更多的功能。
- jQuery 不是生產者,而是大自然搬運工。
- jQuery Ajax本質 XMLHttpRequest 或 ActiveXObject
注:2.+版本不再支持IE9以下的瀏覽器
jQuery Ajax 方法列表:
jQuery.get(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
dataType: 返回內容格式,xml, json, script, text, html
jQuery.post(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數
success: 載入成功時回調函數
dataType: 返回內容格式,xml, json, script, text, html
jQuery.getJSON(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.getScript(...)
所有參數:
url: 待載入頁面的URL地址
data: 待發送 Key/value 參數。
success: 載入成功時回調函數。
jQuery.ajax(...)
部分參數:
url:請求地址
type:請求方式,GET、POST(1.9.0之后用method)
headers:請求頭
data:要發送的數據
contentType:即將發送信息至服務器的內容編碼類型(默認: "application/x-www-form-urlencoded; charset=UTF-8")
async:是否異步
timeout:設置請求超時時間(毫秒)
beforeSend:發送請求前執行的函數(全局)
complete:完成之后執行的回調函數(全局)
success:成功之后執行的回調函數(全局)
error:失敗之后執行的回調函數(全局)
accepts:通過請求頭發送給服務器,告訴服務器當前客戶端課接受的數據類型
dataType:將服務器端返回的數據轉換成指定類型
"xml": 將服務器端返回的內容轉換成xml格式
"text": 將服務器端返回的內容轉換成普通文本格式
"html": 將服務器端返回的內容轉換成普通文本格式,在插入DOM中時,如果包含JavaScript標簽,則會嘗試去執行。
"script": 嘗試將返回值當作JavaScript去執行,然后再將服務器端返回的內容轉換成普通文本格式
"json": 將服務器端返回的內容轉換成相應的JavaScript對象
"jsonp": JSONP 格式
使用 JSONP 形式調用函數時,如 "myurl?callback=?" jQuery 將自動替換 ? 為正確的函數名,以執行回調函數
如果不指定,jQuery 將自動根據HTTP包MIME信息返回相應類型(an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string
converters: 轉換器,將服務器端的內容根據指定的dataType轉換類型,並傳值給success回調函數
$.ajax({
accepts: {
mycustomtype: 'application/x-some-custom-type'
},
// Expect a `mycustomtype` back from server
dataType: 'mycustomtype'
// Instructions for how to deserialize a `mycustomtype`
converters: {
'text mycustomtype': function(result) {
// Do Stuff
return newresult;
}
},
});
基於jQueryAjax - Demo
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p>
<input type="button" onclick="XmlSendRequest();" value='Ajax請求' />
</p>
<script type="text/javascript" src="jquery-1.12.4.js"></script>
<script>
function JqSendRequest(){
$.ajax({
url: "http://c2.com:8000/test/",
type: 'GET',
dataType: 'text',
success: function(data, statusText, xmlHttpRequest){
console.log(data);
}
})
}
</script>
</body>
</html>
關於Ajax詳細介紹:點擊這里
三、Django之上傳文件
使用Form表單上傳文件
- upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{# 上傳文件的時候必須要在form標簽中添加屬性 enctype="multipart/form-data" #}
<form method="POST" action="/upload/" enctype="multipart/form-data">
<input type="text" name="user" />
<input type="file" name="img" />
<input type="submit" />
</form>
</body>
</html>
- views.py
from django.shortcuts import render
import os
# Create your views here.
def upload(request):
if request.method == "POST":
user = request.POST.get("user")
# img = request.POST.get("img") # 所有提交的文件名
img = request.FILES.get('img') # 所有提交的文件
img_name = img.name # 獲取文件名
img_abs_name = os.path.join("static", img_name)
with open(img_abs_name, "wb") as f:
for chunk in img.chunks():
f.write(chunk)
return render(request, 'upload.html')
上傳完之后可以通過鏈接 “http://127.0.0.1:8000/static/文件名” 打開圖片
使用js原生XMLHttpRequest對象進行ajax上傳文件
- upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="user" name="user" />
<input type="file" id="img" name="img" />
<input type="button" value="上傳圖片" onclick="uploadFile1();"/>
<script>
// 使用原生的 XMLHttpRequest 上傳圖片
function uploadFile1() {
var form = new FormData();
form.append("user", document.getElementById("user").value);
// 獲取文件對象
var fileObj = document.getElementById("img").files[0];
form.append("img", fileObj);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4){
// 已經接受到全部響應數據,執行以下操作
var data = xhr.responseText;
console.log(data);
}
};
xhr.open("POST", "/upload/", true);
xhr.send(form);
}
</script>
</body>
</html>
- views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
import os
# Create your views here.
def upload(request):
if request.method == "POST":
user = request.POST.get("user")
# img = request.POST.get("img") # 所有提交的文件名
img = request.FILES.get('img') # 所有提交的文件
img_name = img.name
img_abs_name = os.path.join("static", img_name)
with open(img_abs_name, "wb") as f:
for chunk in img.chunks():
f.write(chunk)
return HttpResponse("ok")
return render(request, 'upload.html')
使用jQuery 的ajax上傳文件
該方法需要借助js原生的FormData()將數據封裝到該對象中,並且不支持低版本的瀏覽器,例如IE5、IE6
- upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<input type="text" id="user" name="user" />
<input type="file" id="img" name="img" />
<input type="button" value="上傳圖片" onclick="jQueryAjax();"/>
<script src="/static/jquery/jquery-1.12.4.js"></script>
<script>
function jQueryAjax() {
// 獲取文件對象
var fileObj = $("#img")[0].files[0];
// 創建FormData對象
var form = new FormData();
// 將數據封裝到對象中
form.append("img", fileObj);
form.append("user", "aa");
$.ajax({
type: "POST",
url: "/upload/",
data: form,
processData: false,
contentType: false, # 不設置請求頭
sucess: function (arg) {
console.log(arg);
}
})
}
</script>
</body>
</html>
- views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
import os
import json
# Create your views here.
def upload(request):
if request.method == "POST":
user = request.POST.get("user")
# img = request.POST.get("img") # 所有提交的文件名
img = request.FILES.get('img') # 所有提交的文件
img_name = img.name
img_abs_name = os.path.join("static", img_name)
print(img_abs_name)
with open(img_abs_name, "wb") as f:
for chunk in img.chunks():
f.write(chunk)
return HttpResponse("ok")
return render(request, 'upload.html')