Django框架的介紹
-
2005年發布,采用Python語言編寫的開源web框
-
早期的時候Django主做新聞和內容管理的網站
-
一個重量級的 Python Web框架,Django 配備了常用的大部分組件
- 基本配置
- 路由系統
- 原生HTML模板系統
- 視圖 view
- Model模型,數據庫連接和ORM數據庫管理
- 中間件
- Cookie & Seesion
- 分頁
- 數據庫后台管理系統admin
-
Django的用途
- 網站后端開發
- 微信公眾號、微信小程序等后台開發
- 基於HTTP/HTTPS協議的后台服務器開發(tornado/gevent四層)
- 在線語音/圖像識別服務器
- 在線第三方身份驗證服務器等
-
Django的版本
- 最新版本:2.2.x
- 當前教學版本:1.11.8
-
Django的官網
- 官方網址: http://www.djangoproject.com
- 中文文檔(第三方):
- Django的離線文檔
- 解壓縮數據包
django-docs-1.11-en.zip
- 用瀏覽器打開
django-docs-1.11-en/index.html
- 解壓縮數據包
Django的安裝
-
查看已安裝的版本
>>> import django >>> print(django.VERSION) (1, 11, 8, 'final', 0)
-
安裝
- 在線安裝
$ sudo pip3 install django
安裝django的最新版本- 或
$ sudo pip3 install django[==版本]
安裝django的指定版本- 如:
$ sudo pip3 install django==1.11.8
- 離線安裝
- 下載安裝包:
- 安裝離線包
$ tar -xvf Django-1.11.8.tar.gz
$ cd Django-1.11.8
$ sudo python3 setup.py install
- 用wheel離線安裝
- 下載安裝包:
pip3 download -d /home/tarena/django_packs django==1.11.8
- 安裝離線包
- $ pip3 install Django-1.11.8.whl
- 下載安裝包:
- 在線安裝
-
Django的卸載
-
$ pip3 uninstall django
-
Django 的開發環境
- Django 1.11.x 支持 Python 2.7, 3.4, 3.5 和 3.6(長期支持版本 LTS)
- 注: Django 1.11.x 不支持 Python 3.7
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 項目包文件夾
- 項目包的主文件夾(默認與項目名稱一致)
__init__.py
- 包初始化文件,當此項目包被導入(import)時此文件會自動運行
wsgi.py
- WSGI 即 Web Server Gateway Interface
- WEB服務網關接口的配置文件,僅部署項目時使用
urls.py
- 項目的基礎路由配置文件,所有的動態路徑必須先走該文件進行匹配
settings.py
- Django項目的配置文件, 此配置文件中的一些全局變量將為Django框架的運行傳遞一些參數
- setting.py 配置文件,啟動服務時自動調用,
- 此配置文件中也可以定義一些自定義的變量用於作用全局作用域的數據傳遞
- manage.py
-
settings.py
文件介紹-
BASE_DIR
- 用於綁定當前項目的絕對路徑(動態計算出來的), 所有文件都可以依懶此路徑
-
DEBUG
- 用於配置Django項目的啟用模式, 取值:
- True 表示開發環境中使用
調試模式
(用於開發中) - False 表示當前項目運行在
生產環境中
(不啟用調試)
- True 表示開發環境中使用
- 用於配置Django項目的啟用模式, 取值:
-
ALLOWED_HOSTS
- 設置允許訪問到本項目的網絡地址列表,取值:
- [] 空列表,表示只有
127.0.0.1
,localhost
能訪問本項目 - ['*'],表示任何網絡地址都能訪問到當前項目
- ['192.168.1.3', '192.168.3.3'] 表示只有當前兩個主機能訪問當前項目
- 注意:
- 如果要在局域網其它主機也能訪問此主機,啟動方式應使用如下模式:
- [] 空列表,表示只有
python3 manage.py runserver 0.0.0.0:5000
# 指定網絡設備所有主機都可以通過5000端口訪問(需加ALLOWED_HOSTS = ['*']
)
- 設置允許訪問到本項目的網絡地址列表,取值:
-
INSTALLED_APPS
- 指定當前項目中安裝的應用列表
-
MIDDLEWARE
- 用於注冊中間件
-
TEMPLATES
- 用於指定模板的配置信息
-
DATABASES
- 用於指定數據庫的配置信息
-
LANGUAGE_CODE
- 用於指定語言配置
- 取值:
- 英文 :
"en-us"
- 中文 :
"zh-Hans"
- 英文 :
-
TIME_ZONE
- 用於指定當前服務器端時區
- 取值:
- 世界標准時間:
"UTC"
- 中國時區 :
"Asia/Shanghai"
- 世界標准時間:
-
ROOT_URLCONF
- 用於配置根級 url 配置 'mysite1.urls'
- 如:
ROOT_URLCONF = 'mysite1.urls'
注: 此模塊可以通過
from django.conf import settings
導入和使用 -
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:///
- ...
- http 通過 HTTP 訪問該資源。 格式
-
hostname(主機名)
- 是指存放資源的服務器的域名系統(DNS) 主機名、域名 或 IP 地址。
-
port(端口號)
- 整數,可選,省略時使用方案的默認端口;
- 各種傳輸協議都有默認的端口號,如http的默認端口為80,https端口:443
-
path(路由地址)
- 由零或多個“/”符號隔開的字符串,一般用來表示主機上的一個目錄或文件地址。路由地址決定了服務器端如何處理這個請求
-
query(查詢) ?key1=value1&key2=value2
- 可選,用於給動態網頁傳遞參數,可有多個參數,用“&”符號隔開,每個參數的名和值用“=”符號隔開。
-
fragment(信息片斷)
- 字符串,用於指定網絡資源中的片斷。例如一個網頁中有多個名詞解釋,可使用fragment直接定位到某一名詞解釋。
-
注: [] 代表其中的內容可省略
-
視圖函數(view)
-
視圖函數是用於接收一個瀏覽器請求並通過HttpResponse對象返回數據的函數。此函數可以接收瀏覽器請求並根據業務邏輯返回相應的內容給瀏覽器
-
視圖處理的函數的語法格式:
def xxx_view(request[, 其它參數...]): return HttpResponse對象
-
參數:
- request用於綁定HttpRequest對象,通過此對象可以獲取瀏覽器的參數和數據
-
示例:
- 視圖處理函數
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 = [ url(r'^admin/', admin.site.urls), ... # 此處配置主路由 ]
urlpatterns 是一個路由-視圖函數映射關的列表,此列表的映射關系由url函數來確定
-
url() 函數
- 用於描述路由與視圖函數的對應關系
- 模塊
from django.conf.urls import url
- 語法:
- url(regex, views, name=None)
- 參數:
- regex: 字符串類型,匹配的請求路徑,允許是正則表達式
- views: 指定路徑所對應的視圖處理函數的名稱
- name: 為地址起別名,在模板中地址反向解析時使用
每個正則表達式前面的r表示
'\'
不轉義的原始字符串
- 練習1
-
建立一個小網站:
- 輸入網址: http://127.0.0.1:8000, 在網頁中輸出 : 這是我的首頁
- 輸入網址: http://127.0.0.1:8000/page1, 在網頁中輸出 : 這是編號為1的網頁
- 輸入網址: http://127.0.0.1:8000/page2, 在網頁中輸出 : 這是編號為2的網頁
#views.py寫入: from django.http import HttpResponse def index(request): http='<h1>這是主頁</h1>' return HttpResponse(http) def page_view(request): http="<h1>這是編號為1頁面</h1>" return HttpResponse(http) def page2_view(request): http='<h1>這是編號為2頁面</h1>' return HttpResponse(http) #urls.py路由配置: urlpatterns = [ url(r'^admin/', admin.site.urls), #請求http://127.0.0.1:8000/page1 :交由views.page_view方法處理 url(r'^$',views.index), url(r'^page1$',views.page_view), url(r'^page2$',views.page2_view), ]
提示: 主面路由的正則是
r'^$'
-
思考
- 建立如上一百個網頁該怎么辦?
def pagen_view(request,n): html = '<h1>這是編號為%s的網頁</h1>'%(n) return HttpResponse(html) #url.py路由配置: urlpatterns = [ url(r'^admin/', admin.site.urls), #請求http://127.0.0.1:8000/page1 :交由views.page_view方法處理 url(r'^page(\d+)',views.pagen_view) ]
-
帶有分組的路由和視圖函數
- 在視圖函數內,可以用正則表達式分組
()
提取參數后用函數位置傳參傳遞給視圖函數 - 一個分組表示一個參數,多個參數需要使用多個分組,並且使用個/隔開
- 練習:
-
定義一個路由的格式為:
-
從路由中提取數據,做相應的操作后返回給瀏覽器
-
如:
輸入: 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
-
def pagens_view(request,m,n,i):
if n == 'add':
s=int(m)+int(i)
html = '<h1>結果:%d</h1>'%s
return HttpResponse(html)
if n == 'sub':
s= int(m) -int(i)
html = '<h1>結果:%d</h1>'%s
return HttpResponse(html)
if n == 'mul':
s= int(m) * int(i)
html = '<h1>結果:%d</h1>'%s
return HttpResponse(html)
#urls.py路由配置
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^(\d+)/(\w+)/(\d+)',views.pagens_view)
]
帶有命名分組的路由和視圖函數
-
在url 的正則表達式中可以使用命名分組(捕獲分組)
-
說明:
- 在視圖函數內,可以用正則表達式分組
(?P<name>pattern)
提取參數后用函數關鍵字傳參傳遞給視圖函數
- 在視圖函數內,可以用正則表達式分組
-
示例:
- 路由配置文件
# file : <項目名>/urls.py # 以下示例匹配 # http://127.0.0.1:8000/person/weimingze/35 # http://127.0.0.1:8000/person/shibowen/29 # http://127.0.0.1:8000/person/xiaowei/9 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^person/(?P<name>\w+)/(?P<age>\d{1,2})',views.person_view), ]
- 路由配置文件
-
練習:
- 訪問地址:
- 最終輸出: 生日為: 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日
def birth_day(request,year,month,ri): html = year + '年' + month + '月' + ri + '日' return HttpResponse(html) #urls.py路由配置 urlpatterns = [ #127.0.0.1:8000/birthday/2019/9/5 url(r'^birthday/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<ri>\d{1,2})',views.birth_day), #127.0.0.1:8000/birthday/9/5/2019 url(r'^birthday/(?P<month>\d{1,2})/(?P<ri>\d{1,2})/(?P<year>\d{4})',views.birth_day) ]
-
PyCharm 社區版針對Django項目調試方法
- 添加自己調式配置
- 選擇 Add Configuration...
- 點擊
+
號添加一個自己的配置- 選擇運行的項目的主模塊位置 manage.py
- 添加 runserver 命令行參數
- 添加自己調式配置
HTTP協議的請求和響應
- 請求是指瀏覽器端通過HTTP協議發送給服務器端的數據
- 響應是指服務器端接收到請求后做相應的處理后再回復給瀏覽器端的數據
[外鏈圖片轉存失敗(img-RSTOfJS3-1567767958155)(images/request_response.png)]
HTTP 請求
-
根據HTTP標准,HTTP請求可以使用多種請求方法。
-
HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法(最常用)
-
HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。
-
HTTP1.1 請求詳述
序號 方法 描述 1 GET 請求指定的頁面信息,並返回實體主體。 2 HEAD 類似於get請求,只不過返回的響應中沒有具體的內容,用於獲取報頭 3 POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。 4 PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。 5 DELETE 請求服務器刪除指定的頁面。 6 CONNECT HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。 7 OPTIONS 允許客戶端查看服務器的性能。 8 TRACE 回顯服務器收到的請求,主要用於測試或診斷。 -
HttpRequest對象
- 視圖函數的第一個參數是HttpRequest對象
- 服務器接收到http協議的請求后,會根據請求數據報文創建HttpRequest對象
- HttpRequest屬性
屬性 | 描述 |
---|---|
path | 字符串,表示請求路由信息 |
path_info | URL字符串 |
method | 字符串,表示HTTP請求方法,常用值:“GET”,“POST” |
encoding | 字符串,表示提交的數據編碼方式.(1,如果為None則表示使用瀏覽器的默認設置,一般為‘UTF-8’。2,這個屬性是可寫的可以通過修改它來修改訪問表單數據使用的編碼,接下來對屬性的任何訪問將使用新的enncoding值) |
GET | QueryDict查詢字典對象,包含get請求方式的所有數據 |
POST | QueryDict查詢字典的對象,包含post請求方式的所有數據 |
FILES | 類似於字典的對象,包含所有上傳文件信息 |
COOKIES | Python字典,包含所有的cookie,鍵和值都為字符串 |
session | 類似於字典的對象,表示當前的回話 |
body | 字符串,請求體的內容(POST和PUT) |
environ | 字符串,客戶端運行的環境變量信息 |
scheme | 請求協議('HTTP'/'HTTPS') |
request.get_full_path() | 請求的完整路徑 |
request.get_host() | 請求的主機 |
request.META | 請求中的元數據(消息頭) |
request.META['REMOTE_ADDR'] :
客戶端IP地址
HTTP 響應
- 當瀏覽者訪問一個網頁時,瀏覽者的瀏覽器會向網頁所在服務器發出請求。當瀏覽器接收並顯示網頁前,此網頁所在的服務器會返回一個包含HTTP狀態碼的信息頭用以響應瀏覽器的請求。
- HTTP狀態碼的英文為HTTP Status Code。
- 下面是常見的HTTP狀態碼:
狀態碼 | 描述 |
---|---|
200 | 請求成功 |
301 | 資源(網頁等)被永久轉移到其他URL |
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 重定響 301 HttpResponseNotModified 未修改 304 HttpResponseBadRequest 錯誤請求 400 HttpResponseNotFound 沒有對應的資源 404 HttpResponseForbidden 請求被禁止 403 HttpResponseServerError 服務器錯誤 500
GET方式傳參
-
GET請求方式中可以通過查詢字符串(Query String)將數據傳遞給服務器
-
URL 格式:
xxx?參數名1=值1&參數名2=值2...
- 如:
http://127.0.0.1:8000/page1?a=100&b=200
- 如:
-
服務器端接收參數
- 判斷 request.method 的值判斷請求方式是否是get請求
if request.method == 'GET': 處理GET請求時的業務邏輯 else: 處理其它請求的業務邏輯
- 獲取客戶端請求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
- 能夠產生get請求方式的場合
- 地址欄手動輸入, 如: http://127.0.0.1:8000/mypage?a=100&b=200
<a href="地址?參數=值&參數=值">
- form表單中的method為get
- 語法
- 判斷 request.method 的值判斷請求方式是否是get請求
<form method='get' action="/user/login">
姓名:<input type="text" name="uname">
</form>
一般查詢字符串的大小會受到瀏覽器的的限制(不建議超過2048字節)
-
練習:
- 訪問地址:http://127.0.0.1:8000/sum?start=整數&stop=整數&step整=字
- 輸出結果為sum(range(start, step, stop)) 和:
- 如:
- 輸入網址: http://127.0.0.1:8000/sum?start=1&stop=101&step=1
- 頁面顯示: 結果: 5050
- 輸入網址: http://127.0.0.1:8000/sum?stop=101&step=2
- 頁面顯示: 結果: 2550
- 輸入網址: http://127.0.0.1:8000/sum?start=1&stop=101&step=2
- 頁面顯示: 結果: 2500
-
練習:
- 訪問地址:http://127.0.0.1:8000/birthday?year=四位整數&month=整數&day=整數
- 最終輸出: 生日為: xxxx年xx月xx日
- 如:
- 輸入網址: http://127.0.0.1:8000/birthday?year=2015&month=12&day=11
- 顯示為: 生日為:2015年12月11日
POST傳遞參數
- 客戶端通過表單等POST請求將數據傳遞給服務器端,如:
<form method='post' action="/login">
姓名:<input type="text" name="username">
<input type='submit' value='登陸'>
</form>
-
服務器端接收參數
- 通過 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 的中間件
MIDDLEWARE = [ ... # 'django.middleware.csrf.CsrfViewMiddleware', ... ]
-
form 表單的name屬性
-
在form表單控件提交數據時,會自動搜索本表單控件內部的子標簽的name屬性及相應的值,再將這些名字和值以鍵-值對的形式提交給action指定的服務器相關位置
-
在form內能自動搜集到的name屬性的標簽的控件有
<input name='xxx'> <select name='yyy'></select> <textarea name='zzz'></textarea>
- 如:
<form action="/page1" method="POST"> <input name="title" type="text" value="請輸入"> <select name="gender"> <option value=1>男</option> <option value=0>女</option> </select> <textarea name="comment" rows="5" cols="10">附言...</textarea> <input type="submit" value="提交"> </form>