不一樣的django2.0筆記

大大楓free發表於2020-11-04

《Django Web框架學習筆記》

Django框架的介紹

起源&現狀

  • 2005年釋出,採用Python語言編寫的開源web框架

  • 早期的時候Django主做新聞和內容管理的

  • 一個重量級的 Python Web框架,Django 配備了常用的大部分元件

    1. 基本配置
    2. 路由系統
    3. 原生HTML模板系統
    4. 檢視 view
    5. Model模型,資料庫連線和ORM資料庫管理
    6. 中介軟體
    7. Cookie & Seesion
    8. 分頁
    9. 資料庫後臺管理系統admin
  • Django的用途

    • 網站後端開發
    • 微信公眾號、微信小程式等後臺開發
    • 基於HTTP/HTTPS協議的後臺伺服器開發
      • 線上語音/影像識別伺服器
      • 線上第三方身份驗證伺服器等
  • Django的版本

    • 最新版本:3.0.x
    • 當前教學版本:2.2.12
  • Django的官網

Django的安裝

  • 檢視已安裝的版本

    >>> import django
    >>> print(django.VERSION)
    (2, 2, 12, 'final', 0)
    
  • 安裝

    1. 線上安裝
      • $ sudo pip3 install django 安裝django的最新版本
      • $ sudo pip3 install django[==版本] 安裝django的指定版本
      • 如:
        • `$ sudo pip3 install django==2.2.12
    2. 離線安裝
      • 下載安裝包:
      • 安裝離線包
        • $ tar -xvf Django-2.2.12.tar.gz
        • $ cd Django-2.2.12
        • $ sudo python3 setup.py install
  • Django的解除安裝

  • $ pip3 uninstall django

  • Django 的開發環境

    • Django 2.2.12 支援 3.5,3.6,3.7,3.8

建立Django專案

建立專案的指令

  • $ django-admin startproject 專案名稱

  • 如:

    • $ django-admin startproject mysite1
  • 執行

    $ cd mysite1
    $ python3 manage.py runserver
    # 或
    $ python3 manage.py runserver 5000  # 指定只能本機使用127.0.0.1的5000埠訪問本機
    

Django專案的目錄結構

  • 示例:

    $ django-admin startproject mysite1
    $ tree mysite1/
    mysite1/
    ├── manage.py
    └── mysite1
        ├── __init__.py
        ├── settings.py
        ├── urls.py
        └── wsgi.py
    
    1 directory, 5 files
    
  • 專案目錄結構解析:

    • manage.py
      • 此檔案是專案管理的主程式,在開發階段用於管理整個專案的開發執行的調式
      • manage.py 包含專案管理的子命令, 如:
        • python3 manage.py runserver 啟動服務
        • python3 manage.py startapp 建立應用
        • python3 manage.py migrate 資料庫遷移
        • ...
    • mysite1 專案資料夾
      • 專案包的主資料夾(預設與專案名稱一致)
      1. __init__.py
        • 包初始化檔案,當此專案包被匯入(import)時此檔案會自動執行
      2. wsgi.py
        • WSGI 即 Web Server Gateway Interface
        • WEB服務閘道器介面的配置檔案,僅部署專案時使用
      3. urls.py
        • 專案的主路由配置檔案,所有的動態路徑必須先走該檔案進行匹配
      4. settings.py
        • Django專案的配置檔案, 此配置檔案中的一些全域性變數將為Django框架的執行傳遞一些引數
        • setting.py 配置檔案,啟動服務時自動呼叫,
        • 此配置檔案中也可以定義一些自定義的變數用於作用全域性作用域的資料傳遞

settings.py 檔案介紹

https://docs.djangoproject.com/en/2.2/ref/settings/

  1. BASE_DIR

    • 用於繫結當前專案的絕對路徑(動態計算出來的), 所有檔案都可以依懶此路徑
  2. DEBUG

    • 用於配置Django專案的啟動模式, 取值:
      1. True 表示開發環境中使用 除錯模式(用於開發中)
      2. False 表示當前專案執行在生產環境中(不啟用除錯)
  3. ALLOWED_HOSTS

    • 設定允許訪問到本專案的host請求頭的值,取值:
      1. [] 空列表,表示只有host請求頭為127.0.0.1, localhost能訪問本專案 - DEBUG = True時生效
      2. [’*’],表示任何請求頭的host都能訪問到當前專案
      3. [‘192.168.1.3’, ‘127.0.0.1’] 表示只有當前兩個host頭的值能訪問當前專案
      • 注意:
        • 如果要在區域網其它主機也能訪問此主機,啟動方式應使用如下模式:
    • python3 manage.py runserver 0.0.0.0:5000 # 指定網路裝置如果內網環境下其他主機想正常訪問該站點,需加`ALLOWED_HOSTS = [‘內網ip’]
  4. INSTALLED_APPS

    • 指定當前專案中安裝的應用列表
  5. MIDDLEWARE

    • 用於註冊中介軟體
  6. TEMPLATES

    • 用於指定模板的配置資訊
  7. DATABASES

    • 用於指定資料庫的配置資訊
  8. LANGUAGE_CODE

    • 用於指定語言配置
    • 取值:
      • 英文 : "en-us"
      • 中文 : "zh-Hans"
  9. TIME_ZONE

    • 用於指定當前伺服器端時區
    • 取值:
      • 世界標準時間: "UTC"
      • 中國時區 : "Asia/Shanghai"
  10. ROOT_URLCONF

    • 用於配置根級 url 配置 ‘mysite1.urls’
    • 如:
      • ROOT_URLCONF = 'mysite1.urls'

注: 此模組可以通過 from django.conf import settings 匯入和使用

URL 介紹

URL定義

  • URL 即統一資源定位符 Uniform Resource Locator

  • 作用:

    • 用來表示網際網路上某個資源的地址。
  • 說明:

    • 網際網路上的每個檔案都有一個唯一的URL,它包含的資訊指出檔案的位置以及瀏覽器應該怎麼處理它。
  • URL的一般語法格式為:

    protocol :// hostname[:port] / path [?query][#fragment]
    
  • 如:

    http://tts.tmooc.cn/video/showVideo?menuId=657421&version=AID201908#subject
    
  • 說明:

    • protocol(協議)

      • http 通過 HTTP 訪問該資源。 格式 HTTP://
      • https 通過安全的 HTTPS 訪問該資源。 格式 HTTPS://
      • file 資源是本地計算機上的檔案。格式: file:///
    • hostname(主機名)

      • 是指存放資源的伺服器的域名系統(DNS) 主機名、域名 或 IP 地址。
    • port(埠號)

      • 整數,可選,省略時使用方案的預設埠;
      • 各種傳輸協議都有預設的埠號,如http的預設埠為80。
    • path(路由地址)

      • 由零或多個“/”符號隔開的字串,一般用來表示主機上的一個目錄或檔案地址。路由地址決定了伺服器端如何處理這個請求
    • query(查詢)

      • 可選,用於給動態網頁傳遞引數,可有多個引數,用“&”符號隔開,每個引數的名和值用“=”符號隔開。
    • fragment(資訊片斷)

      • 字串,用於指定網路資源中的片斷。例如一個網頁中有多個名詞解釋,可使用fragment直接定位到某一名詞解釋。
    • 注: [] 代表其中的內容可省略

Django如何處理一個URL對應的請求

瀏覽器  http://127.0.0.1:8000/page/2003/

1,Django 從配置檔案中 根據 ROOT_URLCONF 找到 主路由檔案;預設情況下,該檔案在 專案同名目錄下的urls; 例如 mysite1/mysite1/urls.py
2,Django 載入 主路由檔案中的 urlpatterns 變數
3,依次匹配 urlpatterns 中的 URL, 匹配到第一個合適的中斷後續匹配
4,匹配成功 - 呼叫對應的檢視函式處理請求,返回響應
5,匹配失敗 - 返回404響應

主路由-urls.py樣例
from django.urls import path
from . import views
urlpatterns = [
    path('admin/', admin.site.urls)
    path('page/2003/', views.page_2003),
    path('page/2004/', views.page_2004),
]

檢視函式(view)

  • 檢視函式是用於接收一個瀏覽器請求並通過HttpResponse物件返回資料的函式。此函式可以接收瀏覽器請求並根據業務邏輯返回相應的內容給瀏覽器

  • 檢視處理的函式的語法格式:

    def xxx_view(request[, 其它引數...]):
        return HttpResponse物件
    
  • 引數:

    • request用於繫結HttpRequest物件,通過此物件可以獲取瀏覽器的引數和資料
  • 返回值

    ​ HttpResponse的物件;Django會提供一系列的response物件;

  • 示例:

    • 檢視處理函式 views.py
      # file : <專案同名資料夾下>/views.py
      from django.http import HttpResponse
      def page1_view(request):
          html = "<h1>這是第1個頁面</h1>"
          return HttpResponse(html)
      

Django 路由配置

  • settings.py 中的ROOT_URLCONF 指定了主路由配置列表urlpatterns的檔案位置
  • urls.py 主路由配置檔案
    # file : <專案同名資料夾>/urls.py
    urlpatterns = [
        path('admin/', admin.site.urls),
        ...  # 此處配置主路由
    ]
    

path() 函式

  • 用於描述路由與檢視函式的對應關係

  • 模組

    • from django.urls import path
  • 語法:

    • path(route, views, name=None)
    • 引數:
      1. route: 字串型別,匹配的請求路徑
      2. views: 指定路徑所對應的檢視處理函式的名稱
      3. name: 為地址起別名,在模板中地址反向解析時使用
  • 練習

    • 建立一個小網站:
      • 輸入網址: http://127.0.0.1:8000, 在網頁中輸出 : 這是我的首頁
      • 輸入網址: http://127.0.0.1:8000/page/1, 在網頁中輸出 : 這是編號為1的網頁
      • 輸入網址: http://127.0.0.1:8000/page/2, 在網頁中輸出 : 這是編號為2的網頁
      • 思考
        • 建立如上一百個網頁該怎麼辦?
path轉換器

語法: <轉換器型別:自定義名>

作用:若轉換器型別匹配到對應型別的資料,則將資料按照關鍵字傳參的方式傳遞給檢視函式

轉換器效果案例
str匹配除了 '/' 之外的非空字串"v1/users/<str:username>"匹配 /v1/users/guoxiaonao
int匹配0或任何正整數。返回一個 int“page/<int:page>” 匹配 /page/100
slug匹配任意由 ASCII 字母或數字以及連字元和下劃線組成的短標籤“detail/<slug:sl>” 匹配 /detail/this-is-django
path匹配非空欄位,包括路徑分隔符 '/'"v1/users/<path:ph>"匹配 /v1/goods/a/b/c
  • 練習:
    • 定義一個路由的格式為:

      • http://127.0.0.1:8000/整數/操作字串/整數
    • 從路由中提取資料,做相應的操作後返回給瀏覽器

    • 如:

    輸入: 127.0.0.1:8000/100/add/200
        頁面顯示結果:300
    輸入: 127.0.0.1:8000/100/sub/200
        頁面顯示結果:-100
    輸入: 127.0.0.1:8000/100/mul/200
        頁面顯示結果:20000
    

re_path()函式

  • 在url 的匹配過程中可以使用正規表示式進行精確匹配

  • 語法:

    • re_path(reg, view, name=xxx)
    • 正規表示式為命名分組模式(?P<name>pattern) ;匹配提取引數後用關鍵字傳參方式傳遞給檢視函式
  • 示例:

    • 路由配置檔案
      # file : <專案同名資料夾>/urls.py
      # 以下示例匹配
      # 可匹配 http://127.0.0.1:8000/20/mul/40
      # 不可匹配 http://127.0.0.1:8000/200/mul/400
      urlpatterns = [
          path('admin/', admin.site.urls),
          re_path(r'^(?P<x>\d{1,2})/(?P<op>\w+)/(?P<y>\d{1,2})$',views.cal_view),
      ]
      
  • 練習:

    • 訪問地址:
      • http://127.0.0.1:8000/birthday/四位數字/一到兩位數字/一到兩位數字
      • http://127.0.0.1:8000/birthday/一到兩位數字/一到兩位數字/四位數字
    • 最終輸出: 生日為: xxxx年xx月xx日
    • 如:
      輸入網址: http://127.0.0.1:8000/birthday/2015/12/11
      顯示為: 生日為:2015年12月11日
      輸入網址: http://127.0.0.1:8000/birthday/2/28/2008
      顯示為: 生日為:2008年2月28日

HTTP協議的請求和響應

  • 請求是指瀏覽器端通過HTTP協議傳送給伺服器端的資料
  • 響應是指伺服器端接收到請求後做相應的處理後再回復給瀏覽器端的資料

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-xdAM1U2Y-1604448925392)(images/request_response.png)]

HTTP 請求

POST /v1/tokens HTTP/1.1     -> 起始行

Host: 127.0.0.1:8000         -> headers
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/json
Content-Length: 58
Origin: http://127.0.0.1:7000
Connection: keep-alive
Referer: http://127.0.0.1:7000/dadashop/templates/login.html

{"username":"guoxiaonao"}     -> body 
  • 根據HTTP標準,HTTP請求可以使用多種請求方法。

  • HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法(最常用)

  • HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

  • HTTP1.1 請求詳述

    序號方法描述
    1GET請求指定的頁面資訊,並返回實體主體。
    2HEAD類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭
    3POST向指定資源提交資料進行處理請求(例如提交表單或者上傳檔案)。資料被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
    4PUT從客戶端向伺服器傳送的資料取代指定的文件的內容。
    5DELETE請求伺服器刪除指定的頁面。
    6CONNECTHTTP/1.1協議中預留給能夠將連線改為管道方式的代理伺服器。
    7OPTIONS允許客戶端檢視伺服器的效能。
    8TRACE回顯伺服器收到的請求,主要用於測試或診斷。
  • HttpRequest物件

    • 檢視函式的第一個引數是HttpRequest物件
    • 伺服器接收到http協議的請求後,會根據請求資料包文建立HttpRequest物件
    • HttpRequest屬性
      • path_info: URL字串
      • method:字串,表示HTTP請求方法,常用值:‘GET’、‘POST’
      • GET:QueryDict查詢字典的物件,包含查詢字串的所有資料
      • POST:QueryDict查詢字典的物件,包含post表單提交方式的所有資料
      • FILES:類似於字典的物件,包含所有的上傳檔案資訊
      • COOKIES:Python字典,包含所有的cookie,鍵和值都為字串
      • session:似於字典的物件,表示當前的會話
      • body: 字串,請求體的內容(POST或PUT)
      • scheme : 請求協議(‘http’/‘https’)
      • request.get_full_path() : 請求的完整路徑
      • request.get_host() : 請求的主機
      • request.META : 請求中的後設資料(訊息頭)
        • request.META[‘REMOTE_ADDR’] : 客戶端IP地址

HTTP 響應

HTTP/1.0 200 OK                        -> 起始行

Date: Sat, 21 Mar 2020 09:44:15 GMT    -> headers
Server: WSGIServer/0.2 CPython/3.6.8
Content-Type: application/json
X-Frame-Options: SAMEORIGIN
Content-Length: 217
Vary: Origin
Access-Control-Allow-Origin: *

{"code": 200, "username": "guoxiaonao"} -> body 
  • 當瀏覽者訪問一個網頁時,瀏覽者的瀏覽器會向網頁所在伺服器發出請求。當瀏覽器接收並顯示網頁前,此網頁所在的伺服器會返回一個包含HTTP狀態碼的資訊頭用以響應瀏覽器的請求。

  • HTTP狀態碼的英文為HTTP Status Code。

  • 下面是常見的HTTP狀態碼:

    • 200 - 請求成功
    • 301 - 永久重定向-資源(網頁等)被永久轉移到其它URL
    • 302 - 臨時重定向
    • 404 - 請求的資源(網頁等)不存在
    • 500 - 內部伺服器錯誤
  • HTTP狀態碼分類

    • HTTP狀態碼由三個十進位制數字組成,第一個十進位制數字定義了狀態碼的型別,後兩個數字沒有分類的作用。HTTP狀態碼共分為5種型別:

      分類分類描述
      1**資訊,伺服器收到請求,需要請求者繼續執行操作
      2**成功,操作被成功接收並處理
      3**重定向,需要進一步的操作以完成請求
      4**客戶端錯誤,請求包含語法錯誤或無法完成請求
      5**伺服器錯誤,伺服器在處理請求的過程中發生了錯誤
  • Django中的響應物件HttpResponse:

    • 建構函式格式:

      • HttpResponse(content=響應體, content_type=響應體資料型別, status=狀態碼)
    • 作用:

      • 向客戶端瀏覽器返回響應,同時攜帶響應體內容
    • 引數:

      • content:表示返回的內容。
      • status_code:返回的HTTP響應狀態碼(預設為200)。
      • content_type:指定返回資料的的MIME型別(預設為"text/html")。瀏覽器會根據這個屬性,來顯示資料。如果是text/html,那麼就會解析這個字串,如果text/plain,那麼就會顯示一個純文字。
        • 常用的Content-Type如下:
          • 'text/html'(預設的,html檔案)
          • 'text/plain'(純文字)
          • 'text/css'(css檔案)
          • 'text/javascript'(js檔案)
          • 'multipart/form-data'(檔案提交)
          • 'application/json'(json傳輸)
        • 'application/xml'(xml檔案)

        注: 關鍵字MIME(Multipurpose Internet Mail Extensions)是指多用途網際網路郵件擴充套件型別。

  • HttpResponse 子類

    型別作用狀態碼
    HttpResponseRedirect重定向302
    HttpResponseNotModified未修改304
    HttpResponseBadRequest錯誤請求400
    HttpResponseNotFound沒有對應的資源404
    HttpResponseForbidden請求被禁止403
    HttpResponseServerError伺服器錯誤500

Django處理GET和POST請求

  • 無論是GET還是POST,統一都由檢視函式接收請求,通過判斷request.method 區分具體的請求動作

  • 樣例:

    if request.method == 'GET':
        處理GET請求時的業務邏輯
    elif request.method == 'POST':
        處理POST請求的業務邏輯
    else:
        其他請求業務邏輯
    

GET處理

  • GET請求動作,一般用於向伺服器獲取資料

  • 能夠產生GET請求的場景:

    • 瀏覽器位址列中輸入URL,回車後

    • <a href="地址?引數=值&引數=值">

    • form表單中的method為get

      <form method='get' action="/user/login">
          姓名:<input type="text" name="uname">
      </form>
      
  • GET請求方式中,如果有資料需要傳遞給伺服器,通常會用查詢字串(Query String)傳遞 【注意:不要傳遞敏感資料】

    • URL 格式: xxx?引數名1=值1&引數名2=值2...

      • 如: http://127.0.0.1:8000/page1?a=100&b=200
    • 伺服器端接收引數

      獲取客戶端請求GET請求提交的資料

      request.GET['引數名']  # QueryDict
      request.GET.get('引數名','預設值')
      request.GET.getlist('引數名')
      # mypage?a=100&b=200&c=300&b=400
      # request.GET=QueryDict({'a':['100'], 'b':['200','400'], 'c':['300']})
      # a = request.GET['a']
      # b = request.GET['b']  # Error
      

POST處理

  • POST請求動作,一般用於向伺服器提交大量資料

  • 客戶端通過表單等POST請求將資料傳遞給伺服器端,如:

    <form method='post' action="/login">
        姓名:<input type="text" name="username">
        <input type='submit' value='登陸'>
    </form>
    
    • form 表單的name屬性

      • 在form表單控制元件提交資料時,會自動搜尋本表單控制元件內部的子標籤的name屬性及相應的值,再將這些名字和值以鍵-值對的形式提交給action指定的伺服器相關位置

      • 在form內能自動蒐集到的name屬性的標籤的控制元件有

        <input name='xxx'>
        <select name='yyy'></select>
        <textarea name='zzz'></textarea>
        
  • 伺服器端接收引數

    • 通過 request.method 來判斷是否為POST請求,如:
    if request.method == 'POST':
        處理POST請求的資料並響應
    else:
        處理非POST 請求的響應
    
  • 使用post方式接收客戶端資料

request.POST[‘引數名’] # request.POST 繫結QueryDict
request.POST.get(‘引數名’,’’)
request.POST.getlist(‘引數名’)


- 取消csrf驗證,否則Django將會拒絕客戶端發來的POST請求

- 取消 csrf 驗證

  - 禁止掉 settings.py 中 MIDDLEWARE 中的 CsrfViewsMiddleWare 的中介軟體

  ```python
  MIDDLEWARE = [
      ...
      # 'django.middleware.csrf.CsrfViewMiddleware',
      ...
  ]
  ```

相關文章