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

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

此文件即可和前端聯系起來,可以在這兒簡單寫個頁面
<h2>展示</h2>
配置路徑
path("show/", views.show_1),在視圖函數中返回該頁面
def show_1(request):
return render(request, 'show_1.html')返回頁面是用的render,第二個參數就是要顯示的html文件
啟動項目后顯示了“展示”,當然,有前端基礎的同學就可以盡情發(fā)揮,設計一個更加完善的頁面

| 基本功能 | 返回指定內容作為 HTTP 響應 | 渲染模板文件并返回包含動態(tài)內容的 HTTP 響應 | 返回一個 HTTP 重定向響應,將用戶跳轉到另一個 URL |
| 常用場景 | 用于返回簡單的字符串、HTML 或其他內容 | 用于返回包含動態(tài)頁面的完整 HTML 響應 | 用于重定向用戶到其他頁面(如成功后的跳轉) |
| 返回內容類型 | 文本、HTML、JSON 或其他任意內容 | 渲染后的 HTML 內容 | 重定向響應,瀏覽器跳轉到目標 URL |
| 函數參數 | 內容(如字符串或 HTML 代碼) | request、模板文件路徑、上下文數據(字典) | URL 名稱、URL 路徑或視圖名稱 |
| 返回對象 | HttpResponse 對象 | HttpResponse 對象(經過模板渲染的 HTML) | HttpResponseRedirect 對象 |
三、傳參
模板文件和視圖函數可以進行相互傳參,主要通過 上下文數據(Context) 進行傳遞。以下是詳細說明:
1、視圖函數到模板文件
視圖函數傳參到模板文件只需添加一個context參數即可,并返回,context數據可包括一般的數據類型(字符串、數字、布爾值等),也可傳一些儲存數據的結構,比如列表、字典等等.
記得在render渲染器中加入context參數
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)在模板文件中接收到的參數,可用{{ }}顯示到頁面上,字典用key值索引,列表用整數索引取值,對于列表和字典的循環(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>頁面結果:

2、模板文件到視圖函數
在定義視圖函數時的參數requests其實是一個對象,內容包括用戶發(fā)送網絡請求后的一些信息,比如用戶填寫的表單等等。
這里我們新配置一個登錄的url進行演示
#添加路徑
path("login/", views.login),
#定義視圖函數
def login(request):
return render(request, 'login.html')
寫一個簡單的表單
<!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>啟動項目,隨便輸入一點數據

提交后會出現如下錯誤:

這是django獨有的安全檢測,解決方法也很簡單,只需在代碼塊中添加這個:
{% csrf_token %}加了之后右鍵檢查網頁源代碼(或按F12),發(fā)現表單中多了一長串value,這一串碼是django內部用來校驗是否是正常我的網頁發(fā)過來的,django會自動讀取,這樣就可以跳過django的安全檢測。

在視圖函數中編寫代碼,以接收并測試傳送數據,因為是表單提交,所以是POST請求
def login(request):
if request.method == 'POST':
print(request.POST)
return render(request, 'login.html')在網頁中輸入數據并提交,發(fā)現控制臺會打印出剛才表單輸入的數據,這其實就是requests請求的參數。

還可以通過取值獲取到這些具體的參數
username = request.POST['user'] password = request.POST['pwd']
四、引入靜態(tài)文件
之前講過一般只需要創(chuàng)建一個應用(app),但如果創(chuàng)建了多個應用,不可能每個應用創(chuàng)建一個templates,一般是整個Django項目共用一個templates,所以會在settings文件中進行配置,以讓所有應用能共用templates。
在settings文件的大概58行加入:
"DIRS": [os.path.join(BASE_DIR, "templates")],

別忘了在前面引入os庫??!
os.path.join(BASE_DIR, "templates") 的作用是將 BASE_DIR(項目的根目錄)與 templates 子目錄拼接成一個絕對路徑,告訴 Django 從這個文件夾中尋找模板文件。
靜態(tài)文件的介紹和一般存放位置前面已經講了,現在來講講靜態(tài)文件在頁面中的引用
前端寫好的文件和一些img之類的,可以應用到模板中。
如果是像我之前那樣在控制臺輸入指令新建的Django文件,則用不了{% static %} 標簽。但可以用文件的相對路徑。
<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 %} 標簽引入靜態(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>但是用這個語法,要用Pycharm創(chuàng)建Django項目,而且需要用專業(yè)版的Pycharm,不然會有報錯,大家有專業(yè)版的可以用這種語法,社區(qū)版的就還是用上面的文件的相對路徑引入即可。

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

獲取請求的方式:
request.POST
結果是一個對象,用來獲取客戶端通過 POST 請求 提交的數據。它是一個類似字典的對象,包含了所有通過 POST 方法提交的表單數據(通常是鍵值對的形式)。
request.GET
是 Django 中用于獲取通過 GET 請求 提交的查詢參數的一個對象。它是一個類似字典的對象,包含了客戶端通過 URL 查詢字符串傳遞的所有參數。
2、響應
像上面介紹的render,還有之前的HttpResponse,還有一個redirect重定向,都是經常用到的視圖響應函數 的工具
redirect重定向是用戶發(fā)送請求后,直接跳轉到另外的網址,比如百度官網之類的,編寫方式如下:
return redirect('https://blog.csdn.net/2403_83182682?type=blog')第一個參數就是要跳轉的網址
三個響應函數的區(qū)別如下:
| 基本功能 | 返回指定內容作為 HTTP 響應 | 渲染模板文件并返回包含動態(tài)內容的 HTTP 響應 | 返回一個 HTTP 重定向響應,將用戶跳轉到另一個 URL |
| 常用場景 | 用于返回簡單的字符串、HTML 或其他內容 | 用于返回包含動態(tài)頁面的完整 HTML 響應 | 用于重定向用戶到其他頁面(如成功后的跳轉) |
| 返回內容類型 | 文本、HTML、JSON 或其他任意內容 | 渲染后的 HTML 內容 | 重定向響應,瀏覽器跳轉到目標 URL |
| 函數參數 | 內容(如字符串或 HTML 代碼) | request、模板文件路徑、上下文數據(字典) | URL 名稱、URL 路徑或視圖名稱 |
| 返回對象 | HttpResponse 對象 | HttpResponse 對象(經過模板渲染的 HTML) | HttpResponseRedirect 對象 |
| 適用場景示例 | 返回簡單消息或 API 響應:HttpResponse("Hello") | 返回渲染的頁面:render(request, "index.html") | 用戶登錄后跳轉:redirect("dashboard") |
六、綜合小案例
經過前面的學習,詳細您對Django以及有了一定的了解,下面進行一個小案例。
需求是定義一個登錄頁面,用戶名或密碼輸出,會提示,正確則跳轉到一個url,內容是所爬取的豆瓣電影排行前25。
可以就在之前的login上修改修改就行
1、源碼展示
視圖函數:
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": "用戶名或密碼錯誤"})
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;
}
/* 調整圖片大小 */
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="提交"/>
<!--只有當error_msg存在時才顯示錯誤信息-->
{% 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、注意事項以及部分解釋
注意視圖函數用了requests請求以及re解析,需在前面引入
import re import requests
下面這段是關于網絡爬蟲的,有基礎的可以看看,沒基礎的直接復制就行。
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)這里的用戶名和密碼是自己設置的,一般來說,用戶名和密碼是不會出現在代碼中的,容易泄露,可以存放于數據庫中,但我圖方便就先這樣了,后面再出一個完整的Django和Mysql連接的博客。
if username == 'edward' and password == '1234':
return render(request, 'douban.html',context)html頁面做得比較簡潔,有前端基礎的同學可以試著改改,使頁面更加美觀。
3、展示
初始界面:

用戶名或密碼輸入錯誤,提示錯誤:

成功登錄,顯示排行榜:
到此這篇關于Django模板語法、請求與響應的文章就介紹到這了,更多相關Django請求與響應內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Django表單提交后實現獲取相同name的不同value值
這篇文章主要介紹了Django表單提交后實現獲取相同name的不同value值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
解決pytorch load huge dataset(大數據加載)
這篇文章主要介紹了解決pytorch load huge dataset(大數據加載)的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-05-05

