三十九、python學習之Django框架(二):請求、URL路徑引數、查詢字串、請求體(表單,非表單)、請求頭
一、請求
1.flask中,利用HTTP協議想伺服器傳參的幾種途徑
1.1 提取URL的特定部分,可以在伺服器端的路由中用正則表示式擷取:
如:/weather/2018
//前端傳送請求: $.ajax({ url:'http://www.baidu.com/weather/2018', type:'get', dataType:'json' }) .done(function(data){ console.log(data) }) .fail(function(error){ console.log(error) }) # flask後盾接受資料: # 使用正則轉換器 @app.route("/weather/<re:userid>") def index(userid): return "%s" % userid
1.2 查詢字串(query string):
形如key1=value1&key2=value2;
// 前端傳送請求 $.ajax({ url:"http://www.baidu.com/?key1=value1&key2=val2", type:"get", dataType:"json", }) .done(function(data){ console.log(data) }) # flask後端獲取查詢字串的方式: @app.route("/", methods=["GET","POST"]) def index(): val1 = request.args.get("key1") return "%s" % val1
1.3 請求體(body)中傳送的資料,比如表單資料,json,xml。
1.4 在http報文的頭(header)中。
2. URL路徑引數:
在定義路由URL時,可以使用正則表示式提取引數的方法從URL中獲取請求引數,Django會將提取的引數直接傳遞到檢視的引數中
2.1未命名引數按照定義順序傳遞:
# urls.py url(r"weather/([a-z]+)/(\d{4})/$", views.weather), # views.py def weather(request, city, year): print("city=%s" % city) print("year=%s" % year) return HttpResponse("weather function")
終端:
2.2 命名引數傳遞:
# 在urls的路由規則中定義引數名
# urls.py
url(r"/weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$", views.weather),
# views.py
def weather(request, city, year):
print("city=%s" % city)
print("year=%s" % year)
return HttpResponse("ok)
終端:
3.Django中的QueryDict物件:
3.1 QD的基本概念:
django中有一個QueryDict物件;
這個物件一般用來儲存瀏覽器傳遞的引數;
一般預設的看成一個字典,但是他和一般的字典的不同之處在於:
- QueryDict這個字典可以用來處理一鍵多值的情況.
- QueryDict這個字典支援get()方法的使用
-
- 如果是一鍵一值:
QueryDict.get(key):獲得的就是當前key對應的value;
- 如果是一鍵一值:
-
- 如果是一鍵多值:
QueryDict.get(key):獲得的就是key對應的最後一個值
– 獲取一鍵多值的方法:
QueryDict.getlist(key):獲取這個鍵對應的所有值
- 如果是一鍵多值:
程式碼例項:
- get():
根據鍵獲取值;
如果一個鍵同時擁有多個值將獲取最後一個值;
如果鍵不存在則返回None值,可以設定預設值進行後續的處理;
# 預設值一般是default,可以省略
QueryDict.get('鍵',預設值)
# 或者:
QueryDict['鍵']
- gitlist():
根據鍵獲取值,值以列表返回,可以獲取指定鍵的所有值
如果鍵不存在則返回空列表[],可以設定預設值進行後續的處理
QueryDict.getlist('鍵',[預設值])
4.查詢字串(QueryString):
什麼是查詢字串:
簡單理解:就是請求地址中的引數部分,統稱為:查詢字串(QueryString)
獲取請求路徑的查詢字串引數,可以通過request.GET屬性獲取,這個方法返回QueryDict物件
程式碼例項:
// 前端傳送請求:
$.ajax({
url:'http://127.0.0.1:8000/reqresp/qs/?a=1&b=2&a=3',
type:'get',
dataType:'json'
})
.done(function(data){
console.log(data)
})
# django部分接受傳送的引數並列印
# 檢視函式
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse("OK")
終端:
重要:
查詢字串不區分請求方式,即假使客戶端進行POST方式請求,依然可以通過request.GET獲取請求中的查詢字串資料.
注意:
- 這裡的request.GET指的不是傳送ajax用的get方法,而是指從url的查詢字串中獲取的引數;
- 同理:request.POST指的不是ajax用的post方法,而是我們從請求體中獲取的引數;
- 通過以上說明就明白:GET和POST這裡指的都是獲取引數的位置,而不是get、post請求
5.請求體:
請求體資料格式不固定,可以是表單型別字串,可以是JSON字串,可以是XML字串,應區別對待。
可以傳送請求體資料的請求方式有 POST、PUT、PATCH、DELETE。
Django預設開啟了CSRF防護,會對上述請求方式進行CSRF防護驗證,在測試時可以關閉CSRF防護機制,方法為在settings.py檔案中註釋掉CSRF中介軟體,如:
註釋掉後,才能進行下面的驗證.
5.1 表單型別(Form Data):
前端傳送的表單型別的請求體資料,可以通過request.POST屬性獲取,返回QueryDict物件
程式碼例項:
# 檢視函式
def get_body(request):
a = request.POST.get('a')
b = request.POST.get('b')
alist = request.POST.getlist('a')
print(a)
print(b)
print(alist)
return HttpResponse("OK")
postman截圖:
注意:
- 如果是表單資料,傳送的請求不但要求body中是表單的鍵值對,也要求請求頭中content-type的型別是application/x-www-form-urlencoded.如果請求中的不是這樣寫的型別,上面的request.POST.get()方法也不可以使用
- 使用request.POST.get()方法需要滿足一下條件:
5.2非表單型別(Non-Form Data)
非表單型別的請求體資料,Django無法自動解析
可以通過request.body屬性獲取最原始的請求體資料,自己按照請求體格式(JSON、XML等)進行解析。
其中: request.body返回bytes型別。
程式碼例項:
要獲取請求體中的如下json資料:
{“a”:1, “b”:2}
檢視函式程式碼:
import json # 引用的是python內建的json模組,用於json格式的轉化
def get_body_json(request):
json_bytes = request.body
json_str = json_bytes.decode()
#python3.6及以上版本中, json.loads()方法可以接收str和bytes型別
#但是python3.5以及以下版本中, json.loads()方法只能接收str, 所以我們的版本如果是
#3.5 需要有上面的編碼步驟.
req_data = json.loads(json_str)
print(req_data['a'])
print(req_data['b'])
return HttpResponse("OK")
功能效果:
6.請求頭:
我們可以銅鼓request.META屬性獲取請求頭headers中的資料;
request.META為字典型別
常見的請求頭:
POST /reqresp/req/ HTTP/1.1
Host: 127.0.0.1:8000
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
Postman-Token: dd531a45-7518-1e8f-63a5-be03ed593471
a=1&b=2&a=3
通過request.META獲取的時候,需要使用如下所示的用法:
引數 | 說明 | 解釋 |
---|---|---|
CONTENT_LENGTH | The length of the request body (as a string). | 請求體的長度(作為字串) |
CONTENT_TYPE | The MIME type of the request body. | 請求主體的MIME型別 |
HTTP_ACCEPT | Acceptable content types for the response. | 響應的可接受內容型別。 |
HTTP_ACCEPT_ENCODING | Acceptable encodings for the response. | 響應的可接受編碼 |
HTTP_ACCEPT_LANGUAGE | Acceptable languages for the response. | 響應的可接受語言。 |
HTTP_HOST | The HTTP Host header sent by the client. | 客戶端傳送的HTTP主機頭。 |
HTTP_REFERER | The referring page, if any. | 參考頁,如果有的話。 |
HTTP_USER_AGENT | The client’s user-agent string | |
QUERY_STRING | The query string, as a single (unparsed) string. | 客戶端的使用者代理字串 |
REMOTE_ADDR | The IP address of the client. | 客戶端的IP地址 |
REMOTE_HOST | The hostname of the client. | 客戶端的主機名 |
REMOTE_USER | The user authenticated by the Web server, if any. | 使用者通過Web伺服器進行認證,如果有的話 |
REQUEST_METHOD | A string such as “GET” or “POST”. | 請求方法,如“GET”或“POST”。 |
SERVER_NAME | The hostname of the server. | 伺服器的主機名 |
SERVER_PORT | The port of the server (as a string). | 伺服器的埠(作為字串) |
具體使用:
def get_headers(request):
# 獲取請求頭的資料型別
value = request.META["CONTENT_TYPE"]
print(value)
return HttpResponse("OK")
實現效果:
7. 其他常用HttpRequest物件屬性:
- method: 一個字串,表示請求使用的HTTP方法,常用值包括:‘GET’, ‘POST’.
- user: 請求的使用者物件.
- path:一個字串,表示請求的頁面的完整路徑,不包含域名和引數部分.
- encoding:一個字串,表示提交的資料的編碼方式
-
- 如果為None則表示使用瀏覽器的預設設定,一般為utf-8.
-
- 這個屬性時可寫的,可以通過修改它來修改訪問表單資料使用的編碼,接下來對屬性的任何訪問將使用新的encoding.
- FILES: 一個類似於字典的物件,包含所有的上傳檔案
效果: