Django基礎教程之請求與相應

SilenceHL 發表於 2021-04-05

宣告:以下內容均為我個人的理解,如果發現錯誤或者疑問可以聯絡我共同探討

本教程為Django基礎教程系列第四篇,前面篇章在以下連結:

Django基礎教程之Django介紹

Django基礎教程之工程搭建

Django基礎教程之配置檔案詳解

前言

Django基礎教程之工程搭建中,檢視相關部分提到過Django中檢視的功能是接受請求,進行業務處理,返回響應。今天就來研究一下Django中的請求與相應部分。

請求

利用HTTP協議向伺服器傳參有幾種途徑?

  • 提取URL的特定部分,可以通過伺服器端路由中用正規表示式擷取;
  • 查詢字串(query string);
  • 請求體(body)中傳送的資料,比如表單資料、json、xml;
  • 在http報文的頭(header)中。

URL路徑引數

在定義路由URL時,可以使用正規表示式提取引數的方法從URL中獲取請求引數,Django會將提取的引數直接傳遞到檢視的傳入引數中。

  • 未命名引數按定義順序傳遞, 如

    url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
    
    def weather(request, city, year):
        print('city=%s' % city)
        print('year=%s' % year)
        return HttpResponse('OK')
  • 命名引數按名字傳遞,如

    url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
    
    def weather(request, year, city):
        print('city=%s' % city)
        print('year=%s' % year)
        return HttpResponse('OK')

QueryDict物件

與python字典不同,QueryDict型別的物件用來處理同一個鍵帶有多個值的情況,HttpRequest物件的屬性GET、POST都是QueryDict型別的物件

  • get方法:根據鍵獲取值,如果一個鍵同時擁有多個值將獲取最後一個值,如果鍵不存在則返回None值,可以設定預設值進行後續處理
  • getlist方法:根據鍵獲取值,值以列表返回,可以獲取指定鍵的所有值,如果鍵不存在則返回空列表,可以設定預設值進行後續處理

查詢字串Query String

獲取請求路徑中的查詢字串引數,可以通過request.GET屬性獲取,返回QueryDict物件。查詢字串不區分請求方式,即假使客戶端進行POST方式的請求,依然可以通過request.GET獲取請求中的查詢字串資料。

請求體

請求體資料格式不固定,可以是表單型別字串,可以是JSON字串,可以是XML字串,應區別對待。

可以傳送請求體資料的請求方式有POSTPUTPATCHDELETE

Django預設開啟了CSRF防護,會對上述請求方式進行CSRF防護驗證,在測試時可以關閉CSRF防護機制,方法為在settings.py檔案中註釋掉CSRF中介軟體

表單 Form Data

前端傳送的表單型別的請求體資料,可以通過request.POST屬性獲取,返回QueryDict物件。request.POST只能用來獲取POST方式的請求體表單資料。

非表單型別 Non-Form Data

非表單型別的請求體資料,Django無法自動解析,可以通過request.body屬性獲取最原始的請求體資料,自己按照請求體格式(JSON、XML等)進行解析。request.body返回bytes型別。

請求頭

可以通過request.META屬性獲取請求頭headers中的資料,request.META為字典型別

常見的請求頭如:

  • CONTENT_LENGTH – 請求體的長度。
  • CONTENT_TYPE – 請求體的型別。
  • HTTP_ACCEPT – 響應的可接受內容型別。
  • HTTP_ACCEPT_ENCODING – 可接受的響應碼。
  • HTTP_ACCEPT_LANGUAGE – 響應的可接受語言。
  • HTTP_HOST – 客戶端傳送的HTTP主機報頭。
  • HTTP_REFERER – 參考頁面。
  • HTTP_USER_AGENT – 客戶機的使用者代理字串。
  • QUERY_STRING – 查詢字串,作為單個(未解析的)字串。
  • REMOTE_ADDR – 客戶端的IP地址。
  • REMOTE_HOST – 客戶機的主機名。
  • REMOTE_USER – Web伺服器認證的使用者。
  • REQUEST_METHOD – 請求方式字串,如”GET”或”POST”。
  • SERVER_NAME – 伺服器的主機名。
  • SERVER_PORT – 伺服器的埠。

其他常用HttpRequest物件屬性

  • method:一個字串,表示請求使用的HTTP方法,常用值包括:’GET’、’POST’。

  • user:請求的使用者物件。

  • path:一個字串,表示請求的頁面的完整路徑,不包含域名和引數部分。

  • encoding:一個字串,表示提交的資料的編碼方式。

    • 如果為None則表示使用瀏覽器的預設設定,一般為utf-8。
    • 這個屬性是可寫的,可以通過修改它來修改訪問表單資料使用的編碼,接下來對屬性的任何訪問將使用新的encoding值。
  • FILES:一個類似於字典的物件,包含所有的上傳檔案。

響應

檢視在接收請求並處理後,必須返回HttpResponse物件或子物件。HttpRequest物件由Django建立,HttpResponse物件由開發人員建立。

HttpResponse

可以使用django.http.HttpResponse來構造響應物件。也可通過HttpResponse物件屬性來設定響應體、狀態碼:

  • content:表示返回的內容。
  • status_code:返回的HTTP響應狀態碼。

響應頭可以直接將HttpResponse物件當做字典進行響應頭鍵值對的設定

HttpResponse子類

Django提供了一系列HttpResponse的子類,可以快速設定狀態碼

  • HttpResponseRedirect 301
  • HttpResponsePermanentRedirect 302
  • HttpResponseNotModified 304
  • HttpResponseBadRequest 400
  • HttpResponseNotFound 404
  • HttpResponseForbidden 403
  • HttpResponseNotAllowed 405
  • HttpResponseGone 410
  • HttpResponseServerError 500

JsonResponse

若要返回json資料,可以使用JsonResponse來構造響應物件,作用:

  • 幫助我們將資料轉換為json字串
  • 設定響應頭Content-Typeapplication/json

redirect重定向

Cookie

Cookie,有時也用其複數形式Cookies,指某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。Cookie最早是網景公司的前僱員Lou Montulli在1993年3月的發明。Cookie是由伺服器端生成,傳送給User-Agent(一般是瀏覽器),瀏覽器會將Cookie的key/value儲存到某個目錄下的文字檔案內,下次請求同一網站時就傳送該Cookie給伺服器(前提是瀏覽器設定為啟用cookie)。Cookie名稱和值可以由伺服器端開發自己定義,這樣伺服器可以知道該使用者是否是合法使用者以及是否需要重新登入等。伺服器可以利用Cookies包含資訊的任意性來篩選並經常性維護這些資訊,以判斷在HTTP傳輸中的狀態。Cookies最典型記住使用者名稱。

Cookie是儲存在瀏覽器中的一段純文字資訊,建議不要儲存敏感資訊如密碼,因為電腦上的瀏覽器可能被其它人使用。

Cookie的特點

  • Cookie以鍵值對的格式進行資訊的儲存。
  • Cookie基於域名安全,不同域名的Cookie是不能互相訪問的,如訪問itcast.cn時向瀏覽器中寫了Cookie資訊,使用同一瀏覽器訪問baidu.com時,無法訪問到itcast.cn寫的Cookie資訊。
  • 當瀏覽器請求某網站時,會將瀏覽器儲存的跟網站相關的所有Cookie資訊提交給網站伺服器。

設定Cookie

可以通過HttpResponse物件中的set_cookie方法來設定cookie。

讀取Cookie

可以通過HttpRequest物件的COOKIES屬性來讀取本次請求攜帶的cookie值。request.COOKIES為字典型別

Session

Django專案預設啟用Session。如需禁用session,將上圖中的session中介軟體註釋掉即可。

儲存方式

在settings.py檔案中,可以設定session資料的儲存方式,可以儲存在資料庫、本地快取等。

資料庫

儲存在資料庫中,如下設定可以寫,也可以不寫,這是預設儲存方式

SESSION_ENGINE='django.contrib.sessions.backends.db'

如果儲存在資料庫中,需要在項INSTALLED_APPS中安裝Session應用。

INSTALLED_APPS = [    
          ...
      'django.contrib.sessions',    
      ...
  ]

儲存在資料庫中會生成一個diango_session的表,表結構為:鍵、值、過期時間

本地快取

儲存在本機記憶體中,如果丟失則不能找回,比資料庫的方式讀寫更快。

SESSION_ENGINE='django.contrib.sessions.backends.cache'

混合儲存

優先從本機記憶體中存取,如果沒有則從資料庫中存取。

SESSION_ENGINE='django.contrib.sessions.backends.cached_db'

Redis

在redis中儲存session,需要引入第三方擴充套件,我們可以使用django-redis來解決。

1) 安裝擴充套件

pip install django-redis

2)配置

在settings.py檔案中做如下設定

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    }
}
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "default"

注意

如果redis的ip地址不是本地迴環127.0.0.1,而是其他地址,訪問Django時,可能出現Redis連線錯誤,如下:

解決方法:

修改redis的配置檔案,新增特定ip地址。

Session操作

通過HttpRequest物件的session屬性進行會話的讀寫操作。

1) 以鍵值對的格式寫session。

request.session['鍵']=

2)根據鍵讀取值。

request.session.get('鍵',預設值)

3)清除所有session,在儲存中刪除值部分。

request.session.clear()

4)清除session資料,在儲存中刪除session的整條資料。

request.session.flush()

5)刪除session中的指定鍵及值,在儲存中只刪除某個鍵及對應的值。

del request.session['鍵']

6)設定session的有效期

request.session.set_expiry(value)
  • 如果value是一個整數,session將在value秒沒有活動後過期。
  • 如果value為0,那麼使用者session的Cookie將在使用者的瀏覽器關閉時過期。
  • 如果value為None,那麼session有效期將採用系統預設值,預設為兩週,可以通過在settings.py中設定SESSION_COOKIE_AGE來設定全域性預設值。
本作品採用《CC 協議》,轉載必須註明作者和本文連結