Django學習記錄
一、專案建立
1、使用pycharm建立Django專案
會建立一個跟專案同名的app,在該app中可以設定整個專案主路由、配置資訊等
2、在pycharm 終端使用python3 manage.py 操作django專案。如 python3 manage.py runserver啟動django專案(截圖中的提示表示沒有同步資料庫資訊)
二、URL
Django處理URL請求
瀏覽器位址列 -> http://127.0.0.1:8000/admin
1、Django 從配置檔案中根據ROOT_URLCONF找到主路由檔案;預設情況下,該檔案是專案同名app下的urls.py
2、Django 載入主路由檔案中的urlpatterns變數(包含很多路由的陣列)
3、依次匹配urlpatterns中的path,若匹配到第一個合適的路勁,則會中斷後續匹配
4、匹配成功->呼叫對應的師徒函式處理請求,返回響應
5、匹配失敗-> 返回404
主路由 urls.py 示例 from django.contrib import admin from django.urls import path urlpatterns = [ path('admin/', admin.site.urls), ]
三、檢視函式
定義:檢視函式是用於接收一個瀏覽器請求(httprequest物件)並通過httpresponse物件返回響應的函式。
語法:
def xxx_view(request): pass return HttpResponse物件
ps:第一個引數必須是request
返回值必須是HttpResponse物件
示例:
1、在與專案同名的app下新建urls.py檔案
2、建立檢視函式 page_1_view
from django.http import HttpResponse
def page_1_view(request): html = "<h1>test1</h1>" return HttpResponse(html)
3、在主路由中新增路徑及對應檢視函式
from django.urls import path from . import views # 在當前目錄引用 urlpatterns = [ path('admin/', admin.site.urls), path('page/1', views.page_1_view) #配置路由和檢視函式 ]
path函式詳解:
1、匯入 from django.urls import path
2、語法 path(route, views, name=None)
3、引數 route: 字串型別,匹配請求的路徑。
views:指定路徑對應的檢視處理函式名稱。(views不能新增括號,新增括號之後就是將函式的結果引用過來了,兩者完全不同)
name:為地址起的別名,在模板中地址反向解析時使用
四、path轉換器
語法: <轉換器型別:自定義名稱>
作用:若轉換器型別匹配到對應型別的資料,則將資料按照關鍵字傳參的方式傳給檢視函式
例: path('update/<int:note_id>', views.update_note)
轉換器型別及作用:
轉換器型別 | 作用 | 示例 |
str |
匹配除'/'之外的非空字串 | 'user/<str:username>'匹配'user/wx' |
int | 匹配0或者任何整數,返回一個int | 'page/<int:page>'匹配'page/1' |
slug | 匹配任意由ascll字母或數字以及連字元和下劃線組成的短標籤 | 'detail/<slug:sl>'匹配'detail/test-django' |
path | 匹配非空欄位,包括路徑分隔符'/' | 'test/<path:pa>'匹配'test/a/b/c' |
示例:
views.py def page_view(request): html = f"這是編號為{str(pg)}"的頁面 return HttpResponse(html)
urls.py path('page/<int:pg>', views.page_view)
ps: urls.py中的urlpatterns按從上往下的順序匹配
五、re_path()
定義:在url的匹配中可以使用正則表示式進行精確匹配
語法:re_path(reg, view, name=xxx)
正則表示式為命名分組模式(?P<name>pattern); 匹配提取引數後用關鍵字傳參方式傳遞給檢視函式
示例:
from django.urls import path, re_path urlpatterns = [ path('admin/', admin.site.urls), re_path(r'^(?P<x>\d{1,2})/(?P<y>\w+)/(?P<z>\d{1,2})$', views.page_view()) ]
^ 代表開頭 & 代表結束 P 代表正則匹配 <x> 代表我們給他命名為x \d 匹配數字 {1,2} 匹配1-2位 \w+ 匹配字串
六、請求和響應
Django主要做的是網頁,而請求和響應是網頁十分重要的東西。
請求:指瀏覽器通過http協議傳送給服務端的資料
響應:指服務收到請求後做出響應處理後再回復給瀏覽器的資料。
請求方式:
1、根據http標準,http請求可以使用多種請求方法。
2、http1.0定義了三種請求方發:get、post、head(最常用)。
3、http1.1新增了五種請求方法:options、put、delete、trace、connect。
序號 | 方法 | 描述 |
1 | GET | 請求指定的頁面資訊,並返回實體主體 |
2 | HEAD | 類似於get方法,只是返回的資料中沒有具體的內容,用於獲取報頭 |
3 | POST | 向指定資源提交資料進行處理請求(例如提交表單或上傳檔案),資料被包含在請求中,post請求可能導致新的資源建立或已有的資源修改 |
4 | PUT | 從客戶端向服務端傳送的資料取代指定的文件中的內容 |
5 | DELETE | 請求伺服器刪除指定的頁面 |
6 | CONNECT | http1.1協議中預留給能夠將連線改為管道方式的代理伺服器 |
7 | OPTIONS | 允許客戶端檢視伺服器的效能 |
8 | TRACE | 回顯伺服器收到的請求,主要用於測試或診斷 |
Django中的請求:
1、請求在Django中是檢視函式的第一個引數,即HttpRequest物件。
2、Django接收到http協議的請求後,會根據請求資料報文建立HttpRequest物件。
3、HttpRequest物件通過屬性描述了請求的所有相關資訊。
Django中請求的屬性:
1、path_info:URL字串。
2、method:標識http請求的方法。
3、GET:QueryDict查詢字典的物件,包含get請求方法的所有資料。
4、POST:QueryDict查詢字典的物件,包含post請求方法的所有資料。
5、FILES:類似於字典的物件,包含所有上傳的檔案資訊。
6、COOKIES:python字典,包含所有的cookie,key和value都是字串。
7、session:類似字典的物件,表示當前的會話。
8、body:字串,請求體的內容。
9、scheme:請求協議(http/https).
10、get_full_path():請求的完整路徑。
11、META:請求中的元資料。 META['EMOTE_ADDR']:客戶端IP地址。
響應狀態碼:
200 | 請求成功 |
301 | 永久重定向 |
302 | 臨時重定向 |
404 | 請求的資源不存在 |
500 | 伺服器錯誤 |
響應狀態碼分類:
HTTP狀態碼由三位十進位制數字組成,第一個十進位制數字定義了狀態碼的型別,後兩個數字沒有分類的作用。
分類 | 分類描述 |
1** | 資訊。伺服器收到資訊,需要請求者繼續執行操作 |
2** | 成功。操作被成功接受並處理 |
3** | 重定向。需要進一步的操作以完成請求 |
4** | 客戶端錯誤。請求包含語法錯誤或無法完成的請求 |
5** | 服務端錯誤。服務端在處理請求的過程中發生錯誤 |
Django響應:
建構函式格式:
HttpResponse(content=響應體,content_type=響應體資料型別,status=狀態碼)
作用:
向瀏覽器返回響應,同時攜帶響應體內容
常用的Content-Type:
'text/html' | 預設的,html檔案 |
'text/plain' | 純文字 |
'text/css' | css檔案 |
'text/javascript' | js檔案 |
'multipart/rom-data' | 檔案提交 |
'application/json' | json傳輸 |
'application/xml' | xml檔案 |
HttpResponse子類:
型別 |
作用 | 狀態碼 |
HttpResponseRedirect |
重定向 | 302 |
HttpResponseNotModified | 未修改 | 304 |
HttpResponseBadRequest | 錯誤請求 | 400 |
HttpResponseNotFound | 沒有對應的資源 | 404 |
HttpResponseForbidden | 請求被禁止 | 403 |
HttpResponseServerError | 伺服器錯誤 | 500 |
七、GET和POST請求
GET和POST請求:
無論是GET還是POST,統一由檢視函式接收請求,通過request.methed區分具體的請求操作。
示例:
def test_get_post(request): if request.method == 'GET': pass elif request.method == 'POST': pass else: pass return HttpResponse('--test get post is ok--')
GET處理:
1、GET請求動作,一般用於向伺服器獲取資料
2、能夠產生GET請求的場景:
-瀏覽器位址列中輸入URL後,回車
-<a href='地址?引數=值&引數=值'>
-form表單中的methed為get
3、GET請求中如果有資料需要傳遞給伺服器,通常會用查詢字串(Query String)傳遞。【不要傳遞敏感資料】
-URL格式:xxx?引數名1=值1&引數名2=值2
-如:http://127.0.0.1/page?a=1&b=2
-服務端接收引數。獲取客戶端GET請求的資料
方法示例: request.GET['引數名'] #QueryDict request.GET.get('引數名','預設值') request.GET.getlist('引數名') views.py def test_get_post(request): if request.method == 'GET': print(request.GET['a']) print(request.GET.get('c', 'no c')) print(request.GET.getlist('a')) elif request.method == 'POST': pass else: pass return HttpResponse('--test get post is ok--') urls.py path('test_get_post',views.test_get_post),
POST處理:
1、post請求動作,一般用於向伺服器提交大量/隱私資料
2、客戶端通過表單等POST請求將資料傳遞給伺服器,如:
<form methed='post' action="/login"> 姓名: <input type="text" name="username"> <input type="submit" value="登入"> </form>
3、服務端接收引數:
-通過request.methed來判斷是否為post請求,如:
if request.methed =='POST': 處理post請求的資料並響應 else: 處理非post請求
4、取消csrf驗證,否則Django會拒絕服務端發來的POST請求,返回403
5、使用POST方法接收客戶端資料
request.POST['引數名'] #QueryDict request.POST.get('引數名', '') request.POST.getlist('引數名')
八、Django設計模式及模板層
MTV
MTV代表Model-Template-View(模型-模板-檢視)
M 模型層(Model): 負責與資料庫互動
T 模板層(Template): 負責呈現內容到瀏覽器(HOW)
V 檢視層(View): 負責接收請求、獲取資料、返回結果(WHAT)
模板層
1、定義
模板是可以根據字典資料動態變化的html網頁
模板可以根據檢視中傳遞的字典資料動態生成相應的html網頁
2、模板配置
建立模板資料夾 <專案名>/templates
在settings.py中TEMPLATES配置項
BACKEND: 指定模板的引擎
DIRS: 模板的搜尋目錄(可以是一個也可以是多個)
APP_DIRS: 是否要在應用的templates資料夾中搜索模板檔案
OPTIONS: 有關模板的選項
3、模板的載入方式
方式一:通過loader獲取模板,通過HttpResponse進行響應
在檢視函式中:
from django.template import loader # 1、通過loader載入模板 t = loader.get_template('模板檔名') # 2、將t轉換成HTML字串 html = t.render('字典資料') # 3、用響應物件將返回的字串內容返回給瀏覽器 return HttpResponse(html)
views.py
def test_html(request): from django.template import loader t = loader.get_template('test_html.html') html = t.render() return HttpResponse(html)
urls.py
path('test_html',views.test_html)
test_html.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>來自模板層</h3> </body> </html>
執行結果如下圖:
方式二: 使用render()直接載入並響應模板
在檢視函式中:
from django.shortcuts import render return render(request, '模板檔名', '字典資料')
views.py
def test_html(request): # from django.template import loader # # t = loader.get_template('test_html.html') # html = t.render() # return HttpResponse(html) from django.shortcuts import render return render(request, 'test_html.html')
執行結果如下圖:
4、檢視層與模板層之間的互動
檢視函式中可以將python變數封裝到字典中傳遞給模板
def xxx_view(request): dic = { "變數1": "值1", "變數2": "值2" } return render(request, 'xxx.html', dic)
在模板中可以使用{{變數名}}呼叫檢視函式傳來的變數
views.py
def test_html(request): # from django.template import loader # # t = loader.get_template('test_html.html') # html = t.render() # return HttpResponse(html) from django.shortcuts import render dic = {'name': 'tester', 'age': '17'} return render(request, 'test_html.html', dic)
test_html.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>{{name}}來自模板層<h3> </body> </html>
執行結果如下圖:
5、能從檢視傳遞到模板中的資料型別
str -字串 int -整型 list -陣列 tuple -元組 dict -字典 func -方法 object -類例項化的物件
模板中使用變數的語法:
{{變數名}}
{{變數名.index}}
{{變數名.key}}
{{物件.方法}}
{{函式名}}
views.py
def test_html_param(request): dic = {} dic['int'] = 88 dic['str'] = 'zhangsan' dic['lst'] = ['Tom', 'Jack', 'Lily'] dic['dict'] = {'a': 9, 'b': 8} dic['func'] = say_hi dic['class_obj'] = Test() return render(request, 'test_html_param.html', dic) def say_hi(): return 'hahha' class Test: def say(self): return 'tester'
urls.py
path('test_html_param',views.test_html_param),
test_html_param.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h3>int 是 {{ int }}</h3> <h3>str 是 {{ str }}</h3> <h3>lst 是 {{ lst }}</h3> <h3>lst 是 {{ lst.0 }}</h3> <h3>dict 是 {{ dict }}</h3> <h3>dict['a'] 是 {{ dict.a }}</h3> <h3>function 是 {{ func }}</h3> <h3>class_obj 是 {{ class_obj.say }}</h3> </body> </html>
執行結果如下圖:
6、模板中的標籤
作用:將一些服務端的功能嵌入到模板中,例如流程控制等。
標籤語法:
{%標籤%} ...... {%結束標籤%}
if 標籤
語法:
{% if 條件表示式1 %} ... {% elif 條件表示式2 %} ... {% elif 條件表示式3 %} ... {% else 條件表示式4 %} ... {% endif %}
注意:
if條件表示式裡可以用的運算子 ==, !=, >, <, >=, <=, in, not in, is, is not, not, and, or
在if標記中使用實際括號是無效的語法,如果需要指定他們的優先順序,應使用巢狀的if標記
示例:
views.py
def test_if_for(request): dic = {} dic['x'] = 10 return render(request,'test_if_for.html',dic)
urls.py
path('test_if_for',views.test_if_for),
test_if_for.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試 if和for</title> </head> <body> {% if x > 10 %} 今天天氣很好 {% else %} 今天天氣非常好 {% endif %} </body> </html>
for 標籤
語法:
{% for 變數 in 可迭代物件%} ...迴圈語句 {% empty %} ...可迭代物件無資料時填充的資料 {% endfor %}
內建變數:
變數 | 描述 |
forloop.counter | 迴圈的當前迭代(從1開始索引) |
forloop.counter0 | 迴圈的當前迭代(從0開始索引) |
forloop.revcounter | counter值的倒序 |
forloop.revcounter0 | revcounter值的倒序 |
forloop.first | 如果這是第一次通過迴圈,則為真 |
forloop.last | 如果這是最後一次迴圈,則為真 |
forloop.parentloop | 當巢狀迴圈,parentloop表示外層迴圈 |
示例:
views.py
def test_if_for(request): dic = {} dic['x'] = 10 dic['lst'] = {'Tom', 'Jack', 'Lily'} return render(request,'test_if_for.html',dic)
test_if_for.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>測試 if和for</title> </head> <body> {% if x > 10 %} 今天天氣很好 {% else %} 今天天氣非常好 {% endif %} <br> {% for name in lst %} {% if forloop.first %} $$$$${% endif %} <!--當第一次迴圈的時候會輸出該符號--> <p>{{ forloop.counter }} {{ name }}</p> <!--forloop.counter 從1開始計數--> {% if forloop.last %} ===={% endif %}<!--當第最後一次迴圈的時候會輸出該符號--> {% empty %} 當前無資料 {% endfor %} </body> </html> </body> </html>
執行結果如下圖: