django學習第一天
jinja2模板渲染簡單使用
- 下載安裝
pip install jinja2
使用示例
- html檔案中寫法
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <h1>姓名:{{name}}</h1> <h1>愛好:</h1> <ul> {% for hobby in hobby_list %} <li>{{hobby}}</li> {% endfor %} </ul> </body> </html>
- 檢視中寫法
from wsgiref.simple_server import make_server from jinja2 import Template def index(): with open("index2.html", "r",encoding='utf-8') as f: data = f.read() template = Template(data) # 生成模板檔案 ret = template.render({"name": "于謙", "hobby_list": ["燙頭", "泡吧"]}) # 把資料填充到模板裡面 return [bytes(ret, encoding="utf8"), ]
MVC和MTV框架
-
MVC
web伺服器開發領域裡著名的MVC模式,所謂MVC就是把web應用分為模型(M),控制器(C)和檢視(V)三層,結構說明如下:
M:models 資料庫相關操作 V:views 檢視,也就是業務邏輯相關操作 C:controller 控制器,也就是通過路徑找到對應檢視函式
-
MTV
Django的MTV模式本質上和MVC的一樣的,也是為了各元件間保持鬆藕合關係,只是定義上有些許不同。
M:models 資料庫相關操作 T:templates html檔案相關操作(模板渲染等) V:views 檢視,也就是業務邏輯相關操作 再加上一個url控制器,也就是通過路徑找到對應檢視函式
WSGI
- WSGI(Web Server Gateway Interface)就是一種規範,它定義了web應用程式與web伺服器程式之間的介面格式,實現web應用程式與web伺服器程式間的解耦。
開發的專案分為兩個部分的程式 1、伺服器程式 socket相關功能的模組,wsgiref、uwsgi等等,負責接收網路請求並解析網路請求相關資料,分裝加工成一些可用的資料格式,格式大家都是統一的,方便應用程式的開發 2、應用程式 就是使用接收到的網路請求相關資料,進行邏輯程式碼的開發,比如資料庫相關操作,資料結構的調整,檔案操作等等。。
django
- Django是MTV模式架構的框架。歷史版本介紹,參考官網。
- 下載安裝
pip install django==1.11.9
- 建立專案
可以通過指令來建立,將來還可以通過IDE來進行建立,先看指令的寫法
django-admin startproject mysite #mysite是自己的專案名稱
執行上面的指令之後會生成如下的目錄,當前目錄下會生成mysite的工程,裡面有個主目錄和我們建立的專案目錄同名,在專案目錄下有個manage.py檔案,在主目錄下有setting.py\urls.py\wsgi.py,每個檔案的功能介紹如下:
manage.py ----django專案裡面的工具,通過它可以呼叫django shell和資料庫,啟動關閉專案與專案互動等,不管你將框架分了幾個檔案,必然有一個啟動檔案,其實他們本身就是一個檔案 settings.py ----包含了專案的預設設定,包括資料庫資訊,除錯標誌以及其他一些工作的變數 urls.py ---- 負責把URL模式對映到應用程式 wsgi.py ---- runserver命令就使用wsgiref模組做簡單的web server,後面會看到runserver命令,所有與socket相關的內容都在這個檔案裡面了,目前不需要關注它
在一個專案中可以有多個應用,每個應用完成專案的部分功能,比如微信專案,其中有很多應用,比如朋友圈功能、聊天、支付等等。在django框架看來,每個應用都有自己的邏輯部分,資料庫部分等等,所以我們進行業務邏輯開發的時候,需要建立應用在寫邏輯。
執行專案
- 命令執行
python manage.py runserver 127.0.0.1:8000 ip和port可以不用寫,不寫的話,預設是 127.0.0.1:8000 執行之後,通過瀏覽器訪問127.0.0.1:8000,當看到頁面為It worked!表示成功
建立應用
- 建立應用的指令如下:需要藉助到我們建立的專案中的manage.py檔案
python manage.py startapp app01 #app01為建立的應用名稱
- 建立完應用後的目錄介紹
models.py 資料庫相關內容 views.py 檢視,業務邏輯程式碼相關內容 tests.py 用來寫一些測試程式碼,用來測試我們自己寫的檢視 ...其他的後面再說
pycharm建立django框架結構專案
- 需要用到專業版,此處省略,自己百度建立
通過django來完成一個簡單的web專案
-
第一步 建立檢視函式
在應用資料夾下面的views.py檔案中寫檢視函式,比如: def home(request): #request--environ 請求相關資料,request叫作HTTPRequest物件 return render(request,'home.html') #render方法用來開啟html檔案,對檔案進行模板渲染,第一個引數是request,第二個引數是html檔案路徑(這裡只寫了檔名稱,因為django會自動去templates檔案下面去找html檔案),渲染完成後,返回響應頁面資料,最終交給wsgi中的socket將頁面資料返回給客戶端。
-
第二步:建立html檔案
如果檢視響應的是一個html檔案,那麼就需要再專案目錄下templates資料夾下建立一個html檔案。
為什麼django能夠自動找到templates資料夾下面的html檔案呢?也就是我們使用render方法時,只寫了一個html檔名稱,就能夠自動找到這個html檔案,是因為在django的預設配置中有一個關於templates模板相關功能的配置項,裡面指定了html檔案的存放目錄,找到主目錄下面的settings.py,開啟這個檔案,找到TEMPLATES這個配置,內容如下:``` BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 專案根路徑 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')] #DIRS指的就是html文 件存放路徑的配置,注意,有些版本的django或者通過指令來建立專案時,這個DIRS的配置是空的,需要我們自己指定html檔案的存放路徑,所以如果你發現這個DIRS為空,我們需要自定來配置路徑,可以按照現在這種方式來寫 , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] ```
-
第三步 建立url路徑和函式的對映關係
在專案主目錄的urls.py檔案中的urlpatterns中寫上如下內容
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^admin/',admin.site.urls),#這個是django內建的 url(r'^home/',views.home) ]
url中正則路徑如何找到對應的函式,簡單分析
#虛擬碼 import re path = request.path 當前請求路徑 for item in urlpatterns: ret = re.match(item.regex,path) #item.regex -- ^home/ if ret: item.func(request) #item.func--views.home 函式 break else: pass
簡單介紹幾個request物件的屬性
- 在views.py檔案的檢視函式中列印以下幾個屬性
def home(request): print(request) #wsgi封裝的一個物件,WSGIRequest類的物件 print(request.path) #/home/ 請求路徑 print(request.method) #GET 請求方法 print(request.POST) #獲取post請求提交過來的資料 #<QueryDict:{'username':['root'],'password':['123']}> uname = request.POST.get('username')#取出username資料 return render(request,'home.html')
完成一個簡單登入功能
-
views.py內容如下
一個檢視函式搞定登入功能 def login(request): if request.method == 'GET': return render(request,'login.html') else: print(request.POST) #<QueryDict:{'username':['root'],'password':['123']}> uname = request.POST.get('username') pwd = request.POST.get('password') if uname == 'root' and pwd == '123': return render(request,'xx/home.html') else: return HttpResponse("使用者名稱或密碼錯誤!重新登入")
-
urls.py內容如下
from django.conf.urls import url from django.contrib import admin from app01 import views urlpatterns = [ url(r'^home/',views.home), url(r'^login',views.login), ] ```
-
login.html內容如下
<form action='/login/' method='post'> 使用者名稱:<input type='text' name='username'> 密碼:<input type='password' name='password'> <button>提交</button> </form>
url路由系統
在django中,url中的路徑寫法是正則,正則裡面有無名分組正則,有有名正則分組,那麼對應django中的功能,我們稱之為無名分組路由和有名分組路由
無名分組路由
看寫法,urls.py檔案中內容如下
```
urlpatterns = [
url(r'^books/(\d+)/(/d+)/',views.book),
#正則裡面()分組正則,會將分組中的正則匹配到的內容作為返回值返回
]
簡單分子,虛擬碼
當用戶請求的路徑是它: /books/2019/8
url(r'^books/(\d+)/(\d+)',views.book),
上面路由做的事情:
re.match(^books/(\d+)/,/books/2019/)
2019和8作為位置引數交給了要執行的book檢視函式
檢視函式book的寫法
def book(request,xx,oo):
xx = 2019
oo = 9
pass
```
- 檢視views.py檔案中函式的寫法
#位置傳參,url中正則^books/(\d+)/(\d+)/,那麼第一個()分組匹配到的資料,作為book函式的第二個引數,第二個()分組匹配到的資料,作為book的第二個引數 def book(request,year,month): print('year',year,'month',month) #return HttpResponse('%s所有書籍'%year) return HttpResponse('%s年%s月所有書籍'%(year,month))
使用url路由系統時需要注意的幾個點
```
1.urlpatterns中的元素按照書寫順序從上往下逐一匹配正則表示式,一旦匹配成功則不再繼續。
2.若要從URL中捕獲一個值,只需要在它周圍放置一對圓括號(正則分組匹配)
3.不需要新增一個前導的反斜槓(也就是寫在正則最前面的那個/),因為每個url,都有。例如,應該是^home/ 而不是^/home/。
4.每個正則表示式前面的r,是可選的但是建議加上
5.^home$ 以什麼結尾,以什麼開頭,嚴格限制路徑
```
有名分組路由
其實就是正則中的有名分組,看例項
- urls.py檔案中的寫法
urlpatterns = [ url(r'^admin/',admin.site.urls), url(r'^books/(?P<year>\d+)/(?P<month>\d+)/',views.book), #{'year':2020,'month':6},url將有名分組正則匹配出來的資料,交給了book檢視函式作為關鍵字引數來使用 ]
- views.py檔案中函式的寫法如下
#^books/(?P<year>\d+)/(?P<month>\d+)/ #獲取到url中的有名分組正則匹配到的資料,那麼函式形參名稱必須和有名分組正則的那個名稱相同才可以,也就是按照上面的url來看的話,函式的形參必須是year和month這個兩個名稱,並且關鍵字傳參不需要考慮函式形參的位置。 def book(request,month,year): #print('year',year,'month',month) print(request.path) #/book/2020/6/ #return HttpResponse('%s所有書籍'%year) return HttpResponse("%s年%s月所有書籍"%(year,month))
補充說明
```
當用戶通過瀏覽器訪問django框架完整的專案中的某個路徑時,如果使用者在輸入網址路徑的最後,沒有加上斜槓/,比如http://127.0.0.1:8000/test,那麼django會先將使用者輸入的網址路徑加上一個後置/,也就是將路徑變成http://127.0.0.1:8000/test/,然後給瀏覽器發一個重定向的響應操作,狀態碼為301,那麼瀏覽器拿到這個重定向操作之後,就會自動發起一個這樣的路徑請求http://127.0.0.1:8000/test/,所以當我們開啟瀏覽器控制檯的network功能檢視請求過程時,會看到兩個請求,一個有斜槓,一個沒有。第二個有斜槓的才會走到我們的url.py檔案中的路徑配合和分發對應的檢視的地方。
我們可以通過一個配置項,告訴django,不要自動加路徑後面的斜槓了,但是需要注意的就是你自己寫的url中的正則,也別加後面的斜槓,不然正則匹配不到。
配置項直接寫在settings配置檔案中,任意位置
APPEND_SLASH = False #False表示告訴django,不加路徑後面的斜槓,預設值是True
```
檢視函式中指定預設值
- views.py檔案
在路由沒有匹配任何引數的時候,num使用自己的預設值 在路由中有分組匹配資料的動作,比如url(r'^test/(\d+)/',views.test),使用者輸入網址http://127.0.0.1:8000/test/22/,那麼22就匹配到了,會作為引數傳給我們的test函式,那麼num的值就變成了22 def test(request,num=10): print('number>>>',num) return HttpResponse('test')
- urls.py檔案
urlpatterns = [ url(r'^test/(\d+)/',views.test), ]