前言
之前我們介紹過web應用程式和http協議,簡單瞭解過web開發的概念。Web應用程式的本質
- 接收並解析HTTP請求,獲取具體的請求資訊
- 處理本次HTTP請求,即完成本次請求的業務邏輯處理
- 構造並返回處理結果——HTTP響應
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
while True:
conn, addr = server.accept()
data = conn.recv(1024)
print("data:\n", data)
# 路徑解析
request_path = data.decode('utf-8').split('\r\n')[0].split(' ')[1]
# 邏輯判斷
if request_path == '/':
with open("index.html", "rb") as f:
data = f.read()
# 響應資料
conn.send(b'HTTP/1.1 200 OK\r\n\r\n' + data)
elif request_path == '/login':
with open("login.html", "rb") as f:
data = f.read()
conn.send(b'HTTP/1.1 200 OK\r\n\r\n' + data)
else:
with open("notFound.html", "rb") as f:
data = f.read()
conn.send(b'HTTP/1.1 404 Not Found\r\n\r\n' + data)
那麼什麼是web框架呢?
Web應用框架有助於減輕網頁開發時共通性活動的工作負荷,例如許多框架提供資料庫訪問介面、標準樣板以及會話管理等,可提升程式碼的可再用性。
說簡單點就是web框架用於搭建Web應用程式,免去不同Web應用相同程式碼部分的重複。
一、Django介紹
Python下有許多款不同的 Web 框架。Django是重量級選手中最有代表性的一位。許多成功的網站和APP都基於Django。Django 是一個開放原始碼的 Web 應用框架,由 Python 寫成。Django 遵守 BSD 版權,初次釋出於 2005 年 7 月, 並於 2008 年 9 月釋出了第一個正式版本 1.0 。
Django文件
Django 採用了 MVT 的軟體設計模式,即模型(Model),檢視(View)和模板(Template)。
這個MVT模式並非django首創,在其他的語言裡面也有類似的設計模式MVC,甚至可以說django裡面的MVT事實上是借鑑了MVC模式衍生出來的。
M,Model,模型,是用於完成運算元據庫的。
V,View,檢視,裡面的程式碼就是用於展示給客戶端的頁面效果。
C,Controller,控制器,是一個類或者函式,裡面的程式碼就是用於專案功能邏輯的,一般用於呼叫模型來獲取資料,獲取到的資料透過呼叫檢視檔案返回給客戶端。
而MVT指的是:
- M全拼為Model,與MVC中的M功能相同,負責和資料庫互動,進行資料處理。
- V全拼為View,與MVC中的C功能相同,接收請求,進行業務處理,返回應答。
- T全拼為Template,與MVC中的V功能相同,負責封裝構造要返回的html。
MVT模型的工作流程
路由控制器將請求轉發給對應的檢視函式,完成業務邏輯,檢視函式將從model中獲取的資料嵌入到template的中模板檔案(html)渲染成一個頁面字串,返回給客戶端的流程。
所以我們學習Django重點是四個部分:url路由器+MVT
二、Django下載與執行
2.1、Django的下載
目前我們學習和使用的版本是3.2LTS版本
目前開源軟體釋出一般會有2個不同的分支版本:
1. 普通發行版本: 經常用於一些新功能,新特性,但是維護週期短,不穩定.
2. 長線支援版本[LongTerm Supper]: 維護週期長,穩定
軟體版本格式: 大版本.小版本.修訂號
大版本一般是專案內容/軟體的核心架構發生改動, 以前的程式碼已經不適用於新的版本
小版本一般是功能的刪減, 刪一個功能,小版本+1, 減一個功能,小版本+1
修訂號一般就是原來的程式碼出現了bug, 會針對bug程式碼進行修復, 此時就會增加修訂號的數值
官網: http://www.djangoproject.com
文件:https://docs.djangoproject.com/zh-hans/3.2/
在本地安裝
pip install django
pip install django==3.2
pip源:
https://pypi.douban.com/simple/ 豆瓣源
https://pypi.tuna.tsinghua.edu.cn/simple 清華源
使用格式:
pip install django -i https://pypi.douban.com/simple/
# 檢視django版本號
django-admin --version
當然在以後開發或者學習中,我們肯定都會遇到在一臺開發機子中,執行多個專案的情況,有時候還會出現每個專案的python解析器或者依賴包的版本有差異.
2.2、Django的啟動執行
建立虛擬環境並在虛擬環境中下載安裝django包
pip install django==3.2 -i https://pypi.douban.com/simple/
cd ~/Desktop
django-admin startproject demo
完成了以後,直接直接下pycharm下面的終端terminal中使用命令執行django
python manage.py runserver 8090
在瀏覽器中訪問顯示的地址http://127.0.0.1:8090
.效果如下則表示正確安裝了.
runserver預設啟動的wsgi.py檔案作為web伺服器介面
2.3、建立應用
建立自應用:
python manage.py startapp 子應用名稱
Django完整的目錄結構如下:
│─ manage.py # 終端指令碼命令,提供了一系列用於生成檔案或者目錄的命令,也叫腳手架
└─ dome/ # 主應用開發目錄,儲存了專案中的所有開發人員編寫的程式碼, 目錄是生成專案時指定的
│- asgi.py # django3.0以後新增的,用於讓django執行在非同步程式設計模式的一個web應用物件
│- settings.py # 預設開發配置檔案
│- urls.py # 路由列表目錄,用於繫結檢視和url的對映關係
│- wsgi.py # wsgi就是專案執行在wsgi伺服器時的入口檔案
└- __init__.py
└─ app01 # 子應用
│- models # 該應用的模型類模組
│- views # 該應用的檢視模組
│- tests # 該應用的單元測試模組
│- apps # 該應用的一些配置,自動生成
│- admin.py # 該應用的後臺管理系統配置
當然如果每次執行專案都要在終端下輸入命令的話,很麻煩,這時候我們可以藉助pycharm直接自動執行這段命令.當然,這個需要我們在pycharm配置一下的.
可以在runserver 引數後配置修改django監聽的埠和IP地址,當然,只能是127.0.0.1對應的其他地址.不能是任意IP.否則無法執行或訪問!!
2.4、快速使用Django
在django中要提供資料展示給使用者,我們需要完成3個步驟.
需求:利用Django實現一個檢視當前時間的web頁面。
基於MTV模型,設計步驟如下:
- step1:在urls.py中設計url與檢視的對映關係。
- step2:建立子應用,在views.py中構建檢視函式。
- step3:將變數嵌入到模板中返回客戶端。
(1)建立子應用
python manage.py startapp 子應用名稱
子應用的名稱將來會作為目錄名而存在,所以不能出現特殊符號,不能出現中文等多位元組的字元.
(2) 繫結路由
demo/urls.py
程式碼:
from django.contrib import admin
from django.urls import path
from home.views import index
urlpatterns = [
path('admin/', admin.site.urls),
path("timer", timer),
]
(3)檢視函式
home/view.py
,程式碼:
from django.shortcuts import render,HttpResponse
# Create your views here.
import datetime
def timer(request):
now=datetime.datetime.now().strftime("%Y-%m-%d %X")
#return HttpResponse(now)
return render(request,"timer.html",{"now":now})
(4)構建模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
span{
color: red;
}
</style>
</head>
<body>
<h3>當前時間:<span>{{ now }}</span></h3>
</body>
</html>
因為上面我們繫結timer檢視函式的url地址是timer,所以我們可以透過http://127.0.0.1:8080/
拼接url地址timer
來訪問檢視函式
三、路由控制器
Route路由, 是一種對映關係!路由是把客戶端請求的url路徑和使用者請求的應用程式,這裡意指django裡面的檢視進行繫結對映的一種關係。
請求路徑和檢視函式不是一對一對映關係!
在django中所有的路由最終都被儲存到一個變數 urlpatterns.
, urlpatterns必須宣告在主應用下的urls.py總路由中。這是由配置檔案settings設定的。
在django執行中,當客戶端傳送了一個http請求到服務端,服務端的web伺服器則會從http協議中提取url地址, 從程式內部找到專案中新增到urlpatterns裡面的所有路由資訊的url進行遍歷匹配。如果相等或者匹配成功,則呼叫當前url物件的檢視方法。
在給urlpatterns路由列表新增路由的過程中,django一共提供了2個函式給開發者註冊路由.
from django.urls import path # 字串路由
from django.urls import re_path # 正則路由,會把url地址看成一個正則模式與客戶端的請求url地址進行正則匹配
# path和re_path 使用引數一致.僅僅在url引數和接收引數時寫法不一樣
(1)基本使用
path(r'^articles/2003/$', views.special_case_2003),
re_path(r'^articles/([0-9]{4})/$', views.year_archive),
re_path(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive2),
(2)路由分發
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
(3)路由轉發器
有時候上面的內建的url轉換器並不能滿足我們的需求,因此django給我們提供了一個介面可以讓我們自己定義自己的url轉換器。
from django.urls import register_converter
from django.shortcuts import HttpResponse
# 自定義路由轉換器
class MobileConverter(object):
regex = "1[3-9]\d{9}"
def to_python(self,value):
print(type(value))
# 將匹配結果傳遞到檢視內部時使用
# 返回str還是int主要看需求,純數字的可以返回int
return value
def to_url(self,value):
# 將匹配結果用於反向解析傳值時使用
return value
# register_converter(路由轉換器的類名,呼叫別名)
register_converter(MobileConverter,"mobile")
path("index/<mobile:mobile>",index)
def index(request,mobile):
print(":::",type(mobile))
return HttpResponse(f"hi,{mobile}使用者")
(4)反向解析
在使用Django 專案時,一個常見的需求是獲得URL 的最終形式,以用於嵌入到生成的內容中(檢視中和顯示給使用者的URL等)或者用於處理伺服器端的導航(重定向等)。人們強烈希望不要硬編碼這些URL(費力、不可擴充套件且容易產生錯誤)或者設計一種與URLconf 毫不相關的專門的URL 生成機制,因為這樣容易導致一定程度上產生過期的URL。
在需要URL 的地方,對於不同層級,Django 提供不同的工具用於URL 反查:
- 在模板中:使用url模板標籤
- 在Python 程式碼中:使用from django.urls import reverse 函式。
urls.py中為url設定別名引數:
from django.conf.urls import url
from . import views
urlpatterns = [
#...
url(r'^articles/([0-9]{4})/$', views.year_archive, name='news-year-archive'),
#...
]
應用之在模板中反向解析:
<a href="{% url 'news-year-archive' 2012 %}">2012 Archive</a>
<a href="/articles/2012/">2012 Archive</a>
應用之在py文字中反向解析:
from django.shortcuts import redirect
from django.urls import reverse
def redirect_to_year(request):
year = 2006
reverse_path=reverse('news-year-archive', args=(year,))
return redirect(reverse_path) # 等效 redirect("/articles/2006/")