Django模板語法、請求與響應(yīng)的案例詳解
一、引言
像之前那個(gè)頁面,太過簡陋,而且一個(gè)完整的頁面,也不可能只用HttpResponse返回文本,這就可以用django的模板語法,模板語法相當(dāng)于將前后端分離了,前端專寫頁面,寫成一個(gè)html文件,然后后端在視圖函數(shù)中可以通過渲染(render)將前端的html文件渲染為HTTP響應(yīng)。
app文件目錄如下:
app01
│ ├─migrations
│ │ └─__pycache__
│ ├─static
│ │ ├─css
│ │ ├─img
│ │ ├─js
│ │ └─plugins
│ ├─templates
│ └─__pycache__
└─myproject
└─__pycache__
static文件夾用來存放靜態(tài)文件,包括樣式css,圖片img,網(wǎng)頁的js和插件plugins
而templayes是用來存放模板的,一些編寫的html文件通常存放于此
二、模板語法
模板語法如何實(shí)現(xiàn)呢,其實(shí)很簡單,首先得創(chuàng)建一個(gè)html文件,對網(wǎng)頁進(jìn)行設(shè)計(jì),然后在視圖函數(shù)中進(jìn)行返回即可。
新建html文件:
此文件即可和前端聯(lián)系起來,可以在這兒簡單寫個(gè)頁面
<h2>展示</h2>
配置路徑
path("show/", views.show_1),
在視圖函數(shù)中返回該頁面
def show_1(request): return render(request, 'show_1.html')
返回頁面是用的render,第二個(gè)參數(shù)就是要顯示的html文件
啟動(dòng)項(xiàng)目后顯示了“展示”,當(dāng)然,有前端基礎(chǔ)的同學(xué)就可以盡情發(fā)揮,設(shè)計(jì)一個(gè)更加完善的頁面
基本功能 | 返回指定內(nèi)容作為 HTTP 響應(yīng) | 渲染模板文件并返回包含動(dòng)態(tài)內(nèi)容的 HTTP 響應(yīng) | 返回一個(gè) HTTP 重定向響應(yīng),將用戶跳轉(zhuǎn)到另一個(gè) URL |
常用場景 | 用于返回簡單的字符串、HTML 或其他內(nèi)容 | 用于返回包含動(dòng)態(tài)頁面的完整 HTML 響應(yīng) | 用于重定向用戶到其他頁面(如成功后的跳轉(zhuǎn)) |
返回內(nèi)容類型 | 文本、HTML、JSON 或其他任意內(nèi)容 | 渲染后的 HTML 內(nèi)容 | 重定向響應(yīng),瀏覽器跳轉(zhuǎn)到目標(biāo) URL |
函數(shù)參數(shù) | 內(nèi)容(如字符串或 HTML 代碼) | request 、模板文件路徑、上下文數(shù)據(jù)(字典) | URL 名稱、URL 路徑或視圖名稱 |
返回對象 | HttpResponse 對象 | HttpResponse 對象(經(jīng)過模板渲染的 HTML) | HttpResponseRedirect 對象 |
三、傳參
模板文件和視圖函數(shù)可以進(jìn)行相互傳參,主要通過 上下文數(shù)據(jù)(Context) 進(jìn)行傳遞。以下是詳細(xì)說明:
1、視圖函數(shù)到模板文件
視圖函數(shù)傳參到模板文件只需添加一個(gè)context參數(shù)即可,并返回,context數(shù)據(jù)可包括一般的數(shù)據(jù)類型(字符串、數(shù)字、布爾值等),也可傳一些儲(chǔ)存數(shù)據(jù)的結(jié)構(gòu),比如列表、字典等等.
記得在render渲染器中加入context參數(shù)
def show_1(request): list = [1,2,3,4,5] dict = {'name':'zhang','age':23,'from':'China'} context = { "name":"小譚", "age":18, "ishandsome":True, "list":list, "dict":dict } return render(request, 'show_1.html', context)
在模板文件中接收到的參數(shù),可用{{ }}顯示到頁面上,字典用key值索引,列表用整數(shù)索引取值,對于列表和字典的循環(huán)索引,可以使用模板文件中的for循環(huán)。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h2>展示</h2> <h2>姓名:{{name}},年齡:{{age}},帥不帥?{{ishandsome}}的</h2> <div> {% for item in list %} <h1>{{item}}</h1> {% endfor %} </div> <ul> {% for k,v in dict.items %} <li>{{k}}={{v}}</li> {% endfor %} </ul> </body> </html>
頁面結(jié)果:
2、模板文件到視圖函數(shù)
在定義視圖函數(shù)時(shí)的參數(shù)requests其實(shí)是一個(gè)對象,內(nèi)容包括用戶發(fā)送網(wǎng)絡(luò)請求后的一些信息,比如用戶填寫的表單等等。
這里我們新配置一個(gè)登錄的url進(jìn)行演示
#添加路徑 path("login/", views.login), #定義視圖函數(shù) def login(request): return render(request, 'login.html')
寫一個(gè)簡單的表單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>用戶登錄</h1> <form action="/login/" method="post"> #{% csrf_token %} <input type="text" name="user" placeholder="用戶名"> <input type="password" name="pwd" placeholder="密碼"> <input type="submit" value="提交"/> </form> </body> </html>
啟動(dòng)項(xiàng)目,隨便輸入一點(diǎn)數(shù)據(jù)
提交后會(huì)出現(xiàn)如下錯(cuò)誤:
這是django獨(dú)有的安全檢測,解決方法也很簡單,只需在代碼塊中添加這個(gè):
{% csrf_token %}
加了之后右鍵檢查網(wǎng)頁源代碼(或按F12),發(fā)現(xiàn)表單中多了一長串value,這一串碼是django內(nèi)部用來校驗(yàn)是否是正常我的網(wǎng)頁發(fā)過來的,django會(huì)自動(dòng)讀取,這樣就可以跳過django的安全檢測。
在視圖函數(shù)中編寫代碼,以接收并測試傳送數(shù)據(jù),因?yàn)槭潜韱翁峤?,所以是POST請求
def login(request): if request.method == 'POST': print(request.POST) return render(request, 'login.html')
在網(wǎng)頁中輸入數(shù)據(jù)并提交,發(fā)現(xiàn)控制臺(tái)會(huì)打印出剛才表單輸入的數(shù)據(jù),這其實(shí)就是requests請求的參數(shù)。
還可以通過取值獲取到這些具體的參數(shù)
username = request.POST['user'] password = request.POST['pwd']
四、引入靜態(tài)文件
之前講過一般只需要?jiǎng)?chuàng)建一個(gè)應(yīng)用(app),但如果創(chuàng)建了多個(gè)應(yīng)用,不可能每個(gè)應(yīng)用創(chuàng)建一個(gè)templates,一般是整個(gè)Django項(xiàng)目共用一個(gè)templates,所以會(huì)在settings文件中進(jìn)行配置,以讓所有應(yīng)用能共用templates。
在settings文件的大概58行加入:
"DIRS": [os.path.join(BASE_DIR, "templates")],
別忘了在前面引入os庫??!
os.path.join(BASE_DIR, "templates")
的作用是將 BASE_DIR
(項(xiàng)目的根目錄)與 templates
子目錄拼接成一個(gè)絕對路徑,告訴 Django 從這個(gè)文件夾中尋找模板文件。
靜態(tài)文件的介紹和一般存放位置前面已經(jīng)講了,現(xiàn)在來講講靜態(tài)文件在頁面中的引用
前端寫好的文件和一些img之類的,可以應(yīng)用到模板中。
如果是像我之前那樣在控制臺(tái)輸入指令新建的Django文件,則用不了{% static %}
標(biāo)簽。但可以用文件的相對路徑。
<img src="/static/img/picture_1.jpg" alt=""> <link rel="stylesheet" href="static/css/styles.css" rel="external nofollow" > <script src="/static/js/jquery-3.6.0.min.js"></script> <script src="/static/plugins/bootstrap-3.4.1/js/bootstrap.js"></script>
若是在Pycharm中創(chuàng)建的Django,可以使用{% static %}
標(biāo)簽引入靜態(tài)文件
先在模板文件的頂部加入{% load static %}
引入 CSS 文件
<link rel="stylesheet" href="{% static 'css/styles.css' %}" rel="external nofollow" >
引入 JS 文件
<script src="{% static 'js/scripts.js' %}"></script>
引入圖片
<img src="{% static 'img/logo.png' %}" alt="Logo">
引入其他靜態(tài)資源
對于插件或 TypeScript 文件:
<script src="{% static 'plugins/plugin.js' %}"></script> <script src="{% static 'ts/script.ts' %}"></script>
但是用這個(gè)語法,要用Pycharm創(chuàng)建Django項(xiàng)目,而且需要用專業(yè)版的Pycharm,不然會(huì)有報(bào)錯(cuò),大家有專業(yè)版的可以用這種語法,社區(qū)版的就還是用上面的文件的相對路徑引入即可。
五、請求與響應(yīng)
1、請求
用戶發(fā)送請求一般分為GET 請求和POST 請求,GET 和 POST 是 HTTP 的兩種請求方法,GET 用于從服務(wù)器獲取數(shù)據(jù),參數(shù)通過 URL 傳遞,易被緩存,適合傳遞少量、非敏感數(shù)據(jù);POST 用于向服務(wù)器提交數(shù)據(jù),參數(shù)通過請求體傳遞,適合提交表單或大數(shù)據(jù),且更安全。GET 請求參數(shù)可見,長度有限且冪等;POST 參數(shù)不可見,無長度限制,通常會(huì)修改服務(wù)器狀態(tài),不具冪等性。GET 常用于查詢操作,POST 常用于提交數(shù)據(jù)或更新操作。
查詢請求的方式:
requests.method
就對于前面寫的表單,在控制臺(tái)打印請求,就是POST請求
獲取請求的方式:
request.POST
結(jié)果是一個(gè)對象,用來獲取客戶端通過 POST 請求 提交的數(shù)據(jù)。它是一個(gè)類似字典的對象,包含了所有通過 POST 方法提交的表單數(shù)據(jù)(通常是鍵值對的形式)。
request.GET
是 Django 中用于獲取通過 GET 請求 提交的查詢參數(shù)的一個(gè)對象。它是一個(gè)類似字典的對象,包含了客戶端通過 URL 查詢字符串傳遞的所有參數(shù)。
2、響應(yīng)
像上面介紹的render,還有之前的HttpResponse,還有一個(gè)redirect重定向,都是經(jīng)常用到的視圖響應(yīng)函數(shù) 的工具
redirect重定向是用戶發(fā)送請求后,直接跳轉(zhuǎn)到另外的網(wǎng)址,比如百度官網(wǎng)之類的,編寫方式如下:
return redirect('https://blog.csdn.net/2403_83182682?type=blog')
第一個(gè)參數(shù)就是要跳轉(zhuǎn)的網(wǎng)址
三個(gè)響應(yīng)函數(shù)的區(qū)別如下:
基本功能 | 返回指定內(nèi)容作為 HTTP 響應(yīng) | 渲染模板文件并返回包含動(dòng)態(tài)內(nèi)容的 HTTP 響應(yīng) | 返回一個(gè) HTTP 重定向響應(yīng),將用戶跳轉(zhuǎn)到另一個(gè) URL |
常用場景 | 用于返回簡單的字符串、HTML 或其他內(nèi)容 | 用于返回包含動(dòng)態(tài)頁面的完整 HTML 響應(yīng) | 用于重定向用戶到其他頁面(如成功后的跳轉(zhuǎn)) |
返回內(nèi)容類型 | 文本、HTML、JSON 或其他任意內(nèi)容 | 渲染后的 HTML 內(nèi)容 | 重定向響應(yīng),瀏覽器跳轉(zhuǎn)到目標(biāo) URL |
函數(shù)參數(shù) | 內(nèi)容(如字符串或 HTML 代碼) | request 、模板文件路徑、上下文數(shù)據(jù)(字典) | URL 名稱、URL 路徑或視圖名稱 |
返回對象 | HttpResponse 對象 | HttpResponse 對象(經(jīng)過模板渲染的 HTML) | HttpResponseRedirect 對象 |
適用場景示例 | 返回簡單消息或 API 響應(yīng):HttpResponse("Hello") | 返回渲染的頁面:render(request, "index.html") | 用戶登錄后跳轉(zhuǎn):redirect("dashboard") |
六、綜合小案例
經(jīng)過前面的學(xué)習(xí),詳細(xì)您對Django以及有了一定的了解,下面進(jìn)行一個(gè)小案例。
需求是定義一個(gè)登錄頁面,用戶名或密碼輸出,會(huì)提示,正確則跳轉(zhuǎn)到一個(gè)url,內(nèi)容是所爬取的豆瓣電影排行前25。
可以就在之前的login上修改修改就行
1、源碼展示
視圖函數(shù):
def login(request): # 豆瓣電影前25排行 headers = {'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ' 'Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0'} response = requests.get("https://movie.douban.com/top250", timeout=10, headers=headers) response = response.text resp = re.findall(r'<span class="title">(?!.* )(?P<name>.*?)</span>', response) if request.method == 'POST': print(request.method) print(request.POST) username = request.POST['user'] password = request.POST['pwd'] context= { 'name':username, 'password':password, 'resp':resp } if username == 'edward' and password == '1234': return render(request, 'douban.html',context) else: # error_msg 登錄失敗返回信息 return render(request, "login.html", {"error_msg": "用戶名或密碼錯(cuò)誤"}) return render(request, "login.html")
登錄頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; flex-direction: column; text-align: center; } /* 調(diào)整圖片大小 */ img { width: 200px; height: auto; } input[type="text"], input[type="password"], input[type="submit"] { font-size: 18px; padding: 10px; margin: 10px 0; width: 25%; box-sizing: border-box; } input[type="submit"] { background-color: #4CAF50; color: white; border: none; cursor: pointer; } input[type="submit"]:hover { background-color: #45a049; } span { font-size: 8px; color: red; } </style> </head> <body> <h1>用戶登錄</h1> <form action="/login/" method="post"> {% csrf_token %} <input type="text" name="user" placeholder="用戶名"> <input type="password" name="pwd" placeholder="密碼"> <input type="submit" value="提交"/> <!--只有當(dāng)error_msg存在時(shí)才顯示錯(cuò)誤信息--> {% if error_msg %} <span style="color: red">{{ error_msg }}</span> {% endif %} </form> <img src="/static/img/picture_1.jpg" alt=""> </body> </html>
顯示電影排行頁面:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <h1>豆瓣Top25</h1> <div>豆瓣電影前25榜單:</div> <ul> {% for item in resp%} <li>{{item}}</li> {% endfor %} </ul> <div>{{response}}</div> </body> </html>
2、注意事項(xiàng)以及部分解釋
注意視圖函數(shù)用了requests請求以及re解析,需在前面引入
import re import requests
下面這段是關(guān)于網(wǎng)絡(luò)爬蟲的,有基礎(chǔ)的可以看看,沒基礎(chǔ)的直接復(fù)制就行。
headers = {'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) ' 'Version/16.6 Mobile/15E148 Safari/604.1 Edg/131.0.0.0'} response = requests.get("https://movie.douban.com/top250", timeout=10, headers=headers) response = response.text resp = re.findall(r'<span class="title">(?!.* )(?P<name>.*?)</span>', response)
這里的用戶名和密碼是自己設(shè)置的,一般來說,用戶名和密碼是不會(huì)出現(xiàn)在代碼中的,容易泄露,可以存放于數(shù)據(jù)庫中,但我圖方便就先這樣了,后面再出一個(gè)完整的Django和Mysql連接的博客。
if username == 'edward' and password == '1234': return render(request, 'douban.html',context)
html頁面做得比較簡潔,有前端基礎(chǔ)的同學(xué)可以試著改改,使頁面更加美觀。
3、展示
初始界面:
用戶名或密碼輸入錯(cuò)誤,提示錯(cuò)誤:
成功登錄,顯示排行榜:
到此這篇關(guān)于Django模板語法、請求與響應(yīng)的文章就介紹到這了,更多相關(guān)Django請求與響應(yīng)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于Python turtle庫使用時(shí)坐標(biāo)的確定方法
這篇文章主要介紹了關(guān)于Python turtle庫使用時(shí)坐標(biāo)的確定方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值
這篇文章主要介紹了Django表單提交后實(shí)現(xiàn)獲取相同name的不同value值,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05解決pytorch load huge dataset(大數(shù)據(jù)加載)
這篇文章主要介紹了解決pytorch load huge dataset(大數(shù)據(jù)加載)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05Python3 獲取一大段文本之間兩個(gè)關(guān)鍵字之間的內(nèi)容方法
今天小編就為大家分享一篇Python3 獲取一大段文本之間兩個(gè)關(guān)鍵字之間的內(nèi)容方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-10-10Python數(shù)據(jù)分析之Matplotlib數(shù)據(jù)可視化
這篇文章主要介紹了Python數(shù)據(jù)分析之Matplotlib數(shù)據(jù)可視化,Matplotlib?是?Python?中常用的?2D?繪圖庫,它能輕松地將數(shù)據(jù)進(jìn)行可視化,作出精美的圖表2022-08-08Python使用Selenium進(jìn)行Web自動(dòng)化測試
Selenium 是一個(gè)用于 Web 應(yīng)用自動(dòng)化測試的強(qiáng)大工具,可以用來模擬用戶操作瀏覽器,從而測試 Web 應(yīng)用的功能,它支持多種瀏覽器和編程語言,包括 Python,下面我們將介紹如何使用 Selenium 進(jìn)行 Web 自動(dòng)化測試,需要的朋友可以參考下2024-08-08