1. 程式人生 > >三十九、python學習之Django框架(二):請求、URL路徑引數、查詢字串、請求體(表單,非表單)、請求頭

三十九、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()方法需要滿足一下條件:
    (圖片1、2)
    在這裡插入圖片描述

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: 一個類似於字典的物件,包含所有的上傳檔案

效果:
在這裡插入圖片描述