Django模板語(yǔ)法、請(qǐng)求與響應(yīng)的案例詳解
一、引言
像之前那個(gè)頁(yè)面,太過(guò)簡(jiǎn)陋,而且一個(gè)完整的頁(yè)面,也不可能只用HttpResponse返回文本,這就可以用django的模板語(yǔ)法,模板語(yǔ)法相當(dāng)于將前后端分離了,前端專(zhuān)寫(xiě)頁(yè)面,寫(xiě)成一個(gè)html文件,然后后端在視圖函數(shù)中可以通過(guò)渲染(render)將前端的html文件渲染為HTTP響應(yīng)。

app文件目錄如下:
app01
│ ├─migrations
│ │ └─__pycache__
│ ├─static
│ │ ├─css
│ │ ├─img
│ │ ├─js
│ │ └─plugins
│ ├─templates
│ └─__pycache__
└─myproject
└─__pycache__
static文件夾用來(lái)存放靜態(tài)文件,包括樣式css,圖片img,網(wǎng)頁(yè)的js和插件plugins
而templayes是用來(lái)存放模板的,一些編寫(xiě)的html文件通常存放于此
二、模板語(yǔ)法
模板語(yǔ)法如何實(shí)現(xiàn)呢,其實(shí)很簡(jiǎn)單,首先得創(chuàng)建一個(gè)html文件,對(duì)網(wǎng)頁(yè)進(jìn)行設(shè)計(jì),然后在視圖函數(shù)中進(jìn)行返回即可。
新建html文件:

此文件即可和前端聯(lián)系起來(lái),可以在這兒簡(jiǎn)單寫(xiě)個(gè)頁(yè)面
<h2>展示</h2>
配置路徑
path("show/", views.show_1),在視圖函數(shù)中返回該頁(yè)面
def show_1(request):
return render(request, 'show_1.html')返回頁(yè)面是用的render,第二個(gè)參數(shù)就是要顯示的html文件
啟動(dòng)項(xiàng)目后顯示了“展示”,當(dāng)然,有前端基礎(chǔ)的同學(xué)就可以盡情發(fā)揮,設(shè)計(jì)一個(gè)更加完善的頁(yè)面

| 基本功能 | 返回指定內(nèi)容作為 HTTP 響應(yīng) | 渲染模板文件并返回包含動(dòng)態(tài)內(nèi)容的 HTTP 響應(yīng) | 返回一個(gè) HTTP 重定向響應(yīng),將用戶跳轉(zhuǎn)到另一個(gè) URL |
| 常用場(chǎng)景 | 用于返回簡(jiǎn)單的字符串、HTML 或其他內(nèi)容 | 用于返回包含動(dòng)態(tài)頁(yè)面的完整 HTML 響應(yīng) | 用于重定向用戶到其他頁(yè)面(如成功后的跳轉(zhuǎn)) |
| 返回內(nèi)容類(lèi)型 | 文本、HTML、JSON 或其他任意內(nèi)容 | 渲染后的 HTML 內(nèi)容 | 重定向響應(yīng),瀏覽器跳轉(zhuǎn)到目標(biāo) URL |
| 函數(shù)參數(shù) | 內(nèi)容(如字符串或 HTML 代碼) | request、模板文件路徑、上下文數(shù)據(jù)(字典) | URL 名稱(chēng)、URL 路徑或視圖名稱(chēng) |
| 返回對(duì)象 | HttpResponse 對(duì)象 | HttpResponse 對(duì)象(經(jīng)過(guò)模板渲染的 HTML) | HttpResponseRedirect 對(duì)象 |
三、傳參
模板文件和視圖函數(shù)可以進(jìn)行相互傳參,主要通過(guò) 上下文數(shù)據(jù)(Context) 進(jìn)行傳遞。以下是詳細(xì)說(shuō)明:
1、視圖函數(shù)到模板文件
視圖函數(shù)傳參到模板文件只需添加一個(gè)context參數(shù)即可,并返回,context數(shù)據(jù)可包括一般的數(shù)據(jù)類(lèi)型(字符串、數(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ù),可用{{ }}顯示到頁(yè)面上,字典用key值索引,列表用整數(shù)索引取值,對(duì)于列表和字典的循環(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>頁(yè)面結(jié)果:

2、模板文件到視圖函數(shù)
在定義視圖函數(shù)時(shí)的參數(shù)requests其實(shí)是一個(gè)對(duì)象,內(nèi)容包括用戶發(fā)送網(wǎng)絡(luò)請(qǐng)求后的一些信息,比如用戶填寫(xiě)的表單等等。
這里我們新配置一個(gè)登錄的url進(jìn)行演示
#添加路徑
path("login/", views.login),
#定義視圖函數(shù)
def login(request):
return render(request, 'login.html')
寫(xiě)一個(gè)簡(jiǎn)單的表單
<!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ú)有的安全檢測(cè),解決方法也很簡(jiǎn)單,只需在代碼塊中添加這個(gè):
{% csrf_token %}加了之后右鍵檢查網(wǎng)頁(yè)源代碼(或按F12),發(fā)現(xiàn)表單中多了一長(zhǎng)串value,這一串碼是django內(nèi)部用來(lái)校驗(yàn)是否是正常我的網(wǎng)頁(yè)發(fā)過(guò)來(lái)的,django會(huì)自動(dòng)讀取,這樣就可以跳過(guò)django的安全檢測(cè)。

在視圖函數(shù)中編寫(xiě)代碼,以接收并測(cè)試傳送數(shù)據(jù),因?yàn)槭潜韱翁峤?,所以是POST請(qǐng)求
def login(request):
if request.method == 'POST':
print(request.POST)
return render(request, 'login.html')在網(wǎng)頁(yè)中輸入數(shù)據(jù)并提交,發(fā)現(xiàn)控制臺(tái)會(huì)打印出剛才表單輸入的數(shù)據(jù),這其實(shí)就是requests請(qǐng)求的參數(shù)。

還可以通過(guò)取值獲取到這些具體的參數(shù)
username = request.POST['user'] password = request.POST['pwd']
四、引入靜態(tài)文件
之前講過(guò)一般只需要?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庫(kù)?。?/strong>
os.path.join(BASE_DIR, "templates") 的作用是將 BASE_DIR(項(xiàng)目的根目錄)與 templates 子目錄拼接成一個(gè)絕對(duì)路徑,告訴 Django 從這個(gè)文件夾中尋找模板文件。
靜態(tài)文件的介紹和一般存放位置前面已經(jīng)講了,現(xiàn)在來(lái)講講靜態(tài)文件在頁(yè)面中的引用
前端寫(xiě)好的文件和一些img之類(lèi)的,可以應(yīng)用到模板中。
如果是像我之前那樣在控制臺(tái)輸入指令新建的Django文件,則用不了{% static %} 標(biāo)簽。但可以用文件的相對(duì)路徑。
<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)資源
對(duì)于插件或 TypeScript 文件:
<script src="{% static 'plugins/plugin.js' %}"></script>
<script src="{% static 'ts/script.ts' %}"></script>但是用這個(gè)語(yǔ)法,要用Pycharm創(chuàng)建Django項(xiàng)目,而且需要用專(zhuān)業(yè)版的Pycharm,不然會(huì)有報(bào)錯(cuò),大家有專(zhuān)業(yè)版的可以用這種語(yǔ)法,社區(qū)版的就還是用上面的文件的相對(duì)路徑引入即可。

五、請(qǐng)求與響應(yīng)
1、請(qǐng)求
用戶發(fā)送請(qǐng)求一般分為GET 請(qǐng)求和POST 請(qǐng)求,GET 和 POST 是 HTTP 的兩種請(qǐng)求方法,GET 用于從服務(wù)器獲取數(shù)據(jù),參數(shù)通過(guò) URL 傳遞,易被緩存,適合傳遞少量、非敏感數(shù)據(jù);POST 用于向服務(wù)器提交數(shù)據(jù),參數(shù)通過(guò)請(qǐng)求體傳遞,適合提交表單或大數(shù)據(jù),且更安全。GET 請(qǐng)求參數(shù)可見(jiàn),長(zhǎng)度有限且冪等;POST 參數(shù)不可見(jiàn),無(wú)長(zhǎng)度限制,通常會(huì)修改服務(wù)器狀態(tài),不具冪等性。GET 常用于查詢(xún)操作,POST 常用于提交數(shù)據(jù)或更新操作。
查詢(xún)請(qǐng)求的方式:
requests.method
就對(duì)于前面寫(xiě)的表單,在控制臺(tái)打印請(qǐng)求,就是POST請(qǐng)求

獲取請(qǐng)求的方式:
request.POST
結(jié)果是一個(gè)對(duì)象,用來(lái)獲取客戶端通過(guò) POST 請(qǐng)求 提交的數(shù)據(jù)。它是一個(gè)類(lèi)似字典的對(duì)象,包含了所有通過(guò) POST 方法提交的表單數(shù)據(jù)(通常是鍵值對(duì)的形式)。
request.GET
是 Django 中用于獲取通過(guò) GET 請(qǐng)求 提交的查詢(xún)參數(shù)的一個(gè)對(duì)象。它是一個(gè)類(lèi)似字典的對(duì)象,包含了客戶端通過(guò) URL 查詢(xún)字符串傳遞的所有參數(shù)。
2、響應(yīng)
像上面介紹的render,還有之前的HttpResponse,還有一個(gè)redirect重定向,都是經(jīng)常用到的視圖響應(yīng)函數(shù) 的工具
redirect重定向是用戶發(fā)送請(qǐng)求后,直接跳轉(zhuǎn)到另外的網(wǎng)址,比如百度官網(wǎng)之類(lèi)的,編寫(xiě)方式如下:
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 |
| 常用場(chǎng)景 | 用于返回簡(jiǎn)單的字符串、HTML 或其他內(nèi)容 | 用于返回包含動(dòng)態(tài)頁(yè)面的完整 HTML 響應(yīng) | 用于重定向用戶到其他頁(yè)面(如成功后的跳轉(zhuǎn)) |
| 返回內(nèi)容類(lèi)型 | 文本、HTML、JSON 或其他任意內(nèi)容 | 渲染后的 HTML 內(nèi)容 | 重定向響應(yīng),瀏覽器跳轉(zhuǎn)到目標(biāo) URL |
| 函數(shù)參數(shù) | 內(nèi)容(如字符串或 HTML 代碼) | request、模板文件路徑、上下文數(shù)據(jù)(字典) | URL 名稱(chēng)、URL 路徑或視圖名稱(chēng) |
| 返回對(duì)象 | HttpResponse 對(duì)象 | HttpResponse 對(duì)象(經(jīng)過(guò)模板渲染的 HTML) | HttpResponseRedirect 對(duì)象 |
| 適用場(chǎng)景示例 | 返回簡(jiǎn)單消息或 API 響應(yīng):HttpResponse("Hello") | 返回渲染的頁(yè)面:render(request, "index.html") | 用戶登錄后跳轉(zhuǎn):redirect("dashboard") |
六、綜合小案例
經(jīng)過(guò)前面的學(xué)習(xí),詳細(xì)您對(duì)Django以及有了一定的了解,下面進(jìn)行一個(gè)小案例。
需求是定義一個(gè)登錄頁(yè)面,用戶名或密碼輸出,會(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")登錄頁(yè)面:
<!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>顯示電影排行頁(yè)面:
<!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請(qǐng)求以及re解析,需在前面引入
import re import requests
下面這段是關(guān)于網(wǎng)絡(luò)爬蟲(chóng)的,有基礎(chǔ)的可以看看,沒(méi)基礎(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è)置的,一般來(lái)說(shuō),用戶名和密碼是不會(huì)出現(xiàn)在代碼中的,容易泄露,可以存放于數(shù)據(jù)庫(kù)中,但我圖方便就先這樣了,后面再出一個(gè)完整的Django和Mysql連接的博客。
if username == 'edward' and password == '1234':
return render(request, 'douban.html',context)html頁(yè)面做得比較簡(jiǎn)潔,有前端基礎(chǔ)的同學(xué)可以試著改改,使頁(yè)面更加美觀。
3、展示
初始界面:

用戶名或密碼輸入錯(cuò)誤,提示錯(cuò)誤:

成功登錄,顯示排行榜:
到此這篇關(guān)于Django模板語(yǔ)法、請(qǐng)求與響應(yīng)的文章就介紹到這了,更多相關(guān)Django請(qǐng)求與響應(yīng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytorch lstm gru rnn 得到每個(gè)state輸出的操作
這篇文章主要介紹了pytorch lstm gru rnn 得到每個(gè)state輸出的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
Python中解包操作的性能實(shí)測(cè)與最佳實(shí)踐
這篇文章主要為大家詳細(xì)介紹了Python中解包操作的性能實(shí)測(cè)與最佳實(shí)踐,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2025-04-04
Python PyAutoGUI實(shí)現(xiàn)自動(dòng)化任務(wù)應(yīng)用場(chǎng)景示例
這篇文章主要為大家介紹了Python PyAutoGUI實(shí)現(xiàn)自動(dòng)化任務(wù)應(yīng)用場(chǎng)景示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Python3.9.1中使用split()的處理方法(推薦)
這篇文章主要介紹了Python3.9.1中使用split()的處理方法(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02
python中的單引號(hào)雙引號(hào)區(qū)別知識(shí)點(diǎn)總結(jié)
在本篇文章中小編給大家整理了關(guān)于python中的單引號(hào)雙引號(hào)有什么區(qū)別的相關(guān)知識(shí)點(diǎn)以及實(shí)例代碼,需要的朋友們參考下。2019-06-06
Python-OpenCV:cv2.imread(),cv2.imshow(),cv2.imwrite()的區(qū)別
本文主要介紹了OpenCV cv2.imread(),cv2.imshow(),cv2.imwrite()的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06

