HttpResponse 家族”?的常用操作🌟
1. 設置狀態碼 👋
狀態碼是服務器告訴客戶端 “請求處理結果” 的數字暗號(比如?404
?表示 “沒找到頁面”)。Django 里有 3 種設置方式:
方式 1:直接寫數字(簡單粗暴)
HttpResponse(html, status=404)
HttpResponse()是類的實例化,后面講解過程中遇到諸如此類的都是實例化加上傳參噢
- 直接傳?
status=404
,告訴客戶端 “你要的頁面沒找到”~
方式 2:用常量(優雅不易錯)
from django.http import HttpResponseNotFound
# HttpResponseNotFound 的 status_code 就是 404,更語義化
HttpResponse(html, status=HttpResponseNotFound.status_code)
HttpResponseNotFound.status_code
?本質還是?404
,但用常量更易讀,不容易寫錯數字~
方式 3:直接用響應類(最推薦!)
from django.http import HttpResponseNotFound
# 直接返回 HttpResponseNotFound,自動帶 404 狀態碼
HttpResponseNotFound(html)
- Django 給常用狀態碼做了 “專屬響應類”(比如?
HttpResponseNotFound
?對應?404
,HttpResponseServerError
?對應?500
),用這些類更簡潔,還能自動設置狀態碼和默認響應內容~
2. 設置響應頭 📄
響應頭是服務器給客戶端的 “額外信息”(比如自定義頭?name: beifan
),可以用?headers
?參數設置:
from django.http import HttpResponseNotFound
# 用 headers 傳字典,自定義響應頭
HttpResponseNotFound(html, headers={"name": "beifan" # 客戶端能拿到這個頭~
})
- 響應頭是鍵值對,客戶端(比如瀏覽器、Postman)可以讀取這些信息,做特殊處理(比如前端根據頭信息渲染不同內容)~
3. 設置 Cookies 🍪
Cookies 是服務器種在客戶端的 “小餅干”,用來記錄狀態(比如登錄態、偏好設置)。Django 里分兩步:
步驟 1:創建響應對象
from django.http import HttpResponseNotFound
resp = HttpResponseNotFound(html)
步驟 2:種餅干!
# 設置 Cookie:name=beifan,客戶端下次請求會帶著它
resp.set_cookie("name", "beifan")
return resp
?視圖必須要有返回值的!返回響應對象實例
客戶端收到的響應頭長這樣:
'Set-Cookie': 'name=beifan; Path=/; ...'
cookie很長 我們要是自定義要寫好多 所以直接傳參讓set_cookie幫助我們生成
- 這串內容是服務器告訴客戶端:“把?
name=beifan
?存在 Cookie 里,下次請求帶上~” - 客戶端(瀏覽器)會自動保存 Cookie,下次發請求時,在請求頭里帶?
Cookie: name=beifan
,服務器就能認出 “老用戶” 啦~
4. 生成 JSON 響應 📦
前后端交互常用 JSON 格式,Django 有?JsonResponse
?幫我們簡化流程:
傳統方式(手動轉 JSON)
import json
from django.http import HttpResponse
data = {'num': num}
# 手動轉 JSON 字符串 + 設置響應頭
html = json.dumps(data)
return HttpResponse(html, content_type='application/json')
用?JsonResponse
(偷懶神器)
from django.http import JsonResponse
# 直接傳字典,自動轉 JSON + 設置響應頭
return JsonResponse({'num': num})
JsonResponse
?會幫你做兩件事:- 把字典轉成 JSON 字符串(
json.dumps
?的活)。 - 設置響應頭?
Content-Type: application/json
(告訴客戶端 “這是 JSON 數據”)。
- 把字典轉成 JSON 字符串(
- 前端拿到響應后,直接?
JSON.parse
?就能用,超方便~
5. 生成重定向 🚀
重定向是服務器告訴客戶端:“你要的資源不在這,去新地址找~”,常用場景:登錄后跳轉到首頁、舊鏈接換新地址。
臨時重定向(302)
from django.http import HttpResponseRedirect
# 告訴客戶端:臨時去百度,下次可能換地址
return HttpResponseRedirect("https://baidu.com")
- 狀態碼?
302
,客戶端下次請求可能還會走原來的地址(比如 “頁面臨時搬家,過幾天搬回來”)。
永久重定向(301)
from django.http import HttpResponsePermanentRedirect
# 告訴客戶端:永久去百度,以后別來舊地址了
return HttpResponsePermanentRedirect("https://baidu.com")
- 狀態碼?
301
,客戶端會記住 “舊地址失效了,以后直接訪問新地址”(比如 “網站域名更換,永久遷移”)。
總結時間 ?
這 5 個知識點,都是 Django 響應的 “常用招式”:
- 狀態碼:告訴客戶端請求結果(成功 / 失敗 / 跳轉)。
- 響應頭:傳額外信息,比如自定義頭、Cookies。
- Cookies:種在客戶端的小餅干,記錄狀態。
- JSON 響應:前后端數據交互的標準格式。
- 重定向:讓客戶端去新地址找資源。
掌握這些,就能靈活控制服務器給客戶端的響應啦~ 下次寫 Django 視圖,就可以按需選對應的 “響應招式”,輕松實現各種需求~ ?
小練習🐱?🏍
1.?submit
?視圖函數
def submit(request: HttpRequest):# 打印請求體內容,用于調試,查看客戶端發送的原始數據print("submit", request.body) # 判斷請求的方法是否為 POST(表單提交、Ajax POST 等常用)if request.method == 'POST': # 從 POST 請求數據中獲取名為 "text" 的參數值,若不存在則返回 Nonetext = request.POST.get("text") # 如果獲取到的 text 有內容(非空)if text: # 重定向到 result 視圖對應的 URL,參數拼接需注意規范,這里簡單示例return HttpResponseRedirect('http://127.0.0.1:8000/beifan/result') else:# 如果 text 為空,暫時不做額外處理,pass 表示跳過pass # 打開 submit.html 文件(需確保文件路徑正確),以 utf-8 編碼讀取內容html = open('submit.html', encoding="utf-8").read() # 將讀取的 HTML 內容作為響應體,返回給客戶端,通常用于展示頁面return HttpResponse(html)
- 作用:主要處理客戶端對?
submit
?路徑的請求。GET 請求時返回?submit.html
?頁面用于展示(比如表單頁面);POST 請求時嘗試獲取表單里的?text
?字段,若有內容就重定向到?result
?視圖,用于模擬 “提交內容后跳轉結果頁” 的流程,常配合表單提交場景(如評論提交、數據錄入后跳轉反饋頁 )。
2.?result
?視圖函數
def result(request):# 打印請求體內容,調試用,查看客戶端請求該視圖時發送的原始數據print("result", request.body) # 打開 result.html 文件(需確保路徑正確),以 utf-8 編碼讀取內容html = open('result.html', encoding="utf-8").read() # 將讀取的 HTML 內容作為響應體返回,用于展示結果頁面(比如評論提交成功提示頁)return HttpResponse(html)
- 作用:處理客戶端對?
result
?路徑的請求,一般是在?submit
?視圖重定向過來后,返回?result.html
?頁面,用于展示提交后的結果(如提示評論已提交、展示數據處理結果等 ),是流程里 “提交 - 跳轉 - 展示結果” 的最后一環。
這兩段代碼實現了一個簡單的 “表單提交(或模擬提交)- 重定向 - 展示結果” 的基礎流程,可用于搭建類似評論提交、信息錄入并反饋結果的功能頁面,不過實際項目中還需完善錯誤處理(如文件不存在、重定向 URL 拼接規則、POST 數據校驗等 )。
什么情況下使用后端重定向什么時候前端重定向?😎
?
🧩 先搞懂兩個 “工具人”
后端重定向:就是你代碼里的?
HttpResponseRedirect(...)
→ 作用:服務器直接對瀏覽器說:“別在這待著了,快去這個新地址!” 🌐→🚀前端 Axios 重定向:前端用 Axios 發消息給服務器后,自己跳走
→ 作用:瀏覽器收到服務器回復后,自己對自己說:“服務器讓我走啦,我去新地址咯!” 📩→🏃
?
🔍 什么時候必須喊 “后端重定向” 來干活?
當用戶用 “傳統表單” 提交數據時?→ 必用后端重定向!
👉 什么是 “傳統表單”?
就是前端頁面長這樣(你不用寫,前端寫):
<form action="/submit" method="post"><input name="text" type="text"> <!-- 輸入框 --><button type="submit">提交</button> <!-- 提交按鈕 -->
</form>
用戶點 “提交” 后,瀏覽器會整個頁面刷新,像 “重啟” 一樣把數據發給你的?submit
?函數。
👉 為啥必須用后端重定向?
因為頁面都 “重啟” 了,只有服務器能指揮它 “重啟后去哪”。就像你換工作,必須新公司(服務器)發 offer(重定向指令),你才知道去新地方~
👉 對應你的代碼:
你的代碼里,submit.html
?很可能就是這個 “傳統表單” 頁面。所以當?text
?有內容時,用?HttpResponseRedirect
?讓瀏覽器跳去結果頁,完全正確! ?
?
🔍 什么時候必須喊 “前端 Axios” 來干活?
當用戶用 “不刷新頁面” 的方式提交數據時?→ 必用前端重定向!
👉 什么是 “不刷新頁面” 提交?
就是用戶點按鈕后,頁面不動(不閃、不重啟),數據 “偷偷摸摸” 發給服務器。前端會寫這樣的代碼(你不用關心,了解即可):
// 前端代碼(假裝是按鈕點擊后執行)
let text = 輸入框里的內容;
// 用Axios發消息給后端的/submit
Axios.post("/submit", {text: text}).then(回復 => {// 收到服務器說“ok”后,自己跳走window.location.href = "http://127.0.0.1:8000/beifan/result";
});
👉 為啥必須用前端重定向?
因為頁面沒 “重啟”,服務器喊 “去新地址” 它聽不見!就像你在辦公室坐著(頁面沒刷新),老板(服務器)遠程發消息讓你去會議室,必須你自己站起來走(前端自己跳轉)~
👉 這時候你的代碼要改嗎?
要!不能用?HttpResponseRedirect
?了,得告訴前端 “可以跳了”:
if text: # 換成這個:告訴前端“成功啦,你自己跳吧”return JsonResponse({"狀態": "成功"})
📝 終極判斷公式
看用戶提交后頁面會不會 “閃一下”:
- 會閃(傳統表單)→ 用后端重定向(你現在的代碼)
- 不閃(偷偷提交)→ 用前端 Axios 重定向(改后端代碼為返回狀態)
就這么簡單!😉 代碼目前適配 “會閃” 的情況,完全沒問題~
點前端的submit提交按鈕為什么會引起頁面刷新,為什么可以讓服務器做出響應啊
🥳 這個問題超基礎也超重要!
?
為啥點 submit 按鈕會讓頁面 “閃一下”(刷新)?
因為?<button type="submit">
?是 HTML 里的 “特殊按鈕”,它天生就帶著一個 “祖傳使命”:
觸發表單的 “默認提交行為”?→ 也就是讓瀏覽器把表單數據打包,然后重新加載整個頁面,把數據發給服務器~
就像你寄快遞:
- 表單里的輸入框 = 快遞盒里的東西 📦
- submit 按鈕 = 你喊 “快遞員快來取件” 📣
- 頁面刷新 = 快遞員把盒子拿走,同時給你換一個新的頁面(服務器發回來的) 🔄
?
👉 第一步:前端 “撥號”(告訴服務器地址)
前端的表單標簽里,早就寫好了 “要把數據發給誰”:
<form action="/submit" method="post"> <!-- action="/submit" → 數據發給服務器的/submit地址 --><!-- method="post" → 用POST方式發(類似打電話的“加密線路”) --><input name="text"><button type="submit">提交</button>
</form>
就像你打電話前,先輸好了對方的號碼(/submit
)~
?
👉 第二步:瀏覽器 “傳聲”(打包發送數據)
你點 submit 后:
- 瀏覽器會把輸入框里的內容(比如
text
的值)打包成 “數據包裹” 📦 - 按照
action
地址,通過POST
方式,發給你的 Django 服務器 🚀
?
👉 第三步:服務器 “接電話”(處理并回復)
你的 Django 后端早就 “守在電話旁” 了:
urls.py
里配置了/submit
地址對應submit
函數 → 相當于 “聽到鈴聲,接起電話” 📞submit
函數里的request.method == 'POST'
會 “識別來電”,然后用request.POST.get("text")
取出數據 → 相當于 “聽對方說話,記下來” 📝- 最后返回
HttpResponse
或重定向 → 相當于 “掛電話前,說一句回復” 💬
?
👉 第四步:瀏覽器 “聽回復”(刷新顯示新內容)
服務器回復后:
- 瀏覽器會刷新頁面,顯示服務器發回來的內容(可能是新頁面,也可能是重定向后的地址) → 相當于 “掛了電話,看對方發來的短信” 📱
為什么點擊button會觸發打包數據傳給服務器呢
<button>
的 “身份標簽” 決定了它的行為
<button>
按鈕有個關鍵屬性叫type
,就像它的 “工作證”:
- 當
type="submit"
時(這是默認值,就算不寫也會生效!)→ 它就成了 “提交專用按鈕” 📤 - 當
type="button"
時 → 它只是個 “普通按鈕”,點了啥也不會自動提交 🚫
它和<form>
標簽是 “最佳搭檔”
單獨一個<button type="submit">
啥也干不了,必須 “抱大腿”—— 放在<form>
標簽里面才行!
<form>
標簽就像一個 “數據收集箱” 📦,它會:
- 通過
action
屬性記住 “數據要發給誰”(比如action="/submit"
就是發給服務器的/submit
地址) - 通過
method
屬性記住 “用什么方式發”(比如method="post"
)
這一切都是 HTML 規定好的 “自動流程”,不用寫任何額外代碼,瀏覽器會幫你完成從 “點擊” 到 “發送” 的所有步驟~
?
一句話總結:
因為這個按鈕是type="submit"
,并且 “住在”<form>
標簽里,所以點擊時會觸發<form>
的 “自動打包 + 發送” 功能,就像按了開關一樣自然~ 🔌→📤
實戰:?接收 JSON 參數返回 JSON?和?接收表單參數重定向🐱?🐉
需求 1:接收 JSON 參數,返回 JSON 內容
在?myapp/views.py
?中編寫視圖:
from django.http import JsonResponse, HttpResponse
import jsondef receive_json(request):# 處理 POST 請求(通常客戶端發 JSON 用 POST )if request.method == 'POST': try:# 解析請求體的 JSON 數據,request.body 是原始字節數據,先轉字符串再 loadsdata = json.loads(request.body.decode('utf-8')) # 簡單處理:把收到的 JSON 數據原樣返回(也可按需加工,比如新增字段 )return JsonResponse(data) except json.JSONDecodeError:# 如果解析失敗,返回 400 錯誤,告知客戶端數據格式有問題return HttpResponse("Invalid JSON data", status=400) # 非 POST 請求,返回提示(也可根據需求調整,比如支持 GET 傳 JSON 字符串,但 POST 更常用 )return HttpResponse("Only POST requests with JSON data are allowed", status=405)
接著配置路由(關聯視圖 )
測試方式:
可用?curl
?命令測試(終端執行 ):
# 發送 JSON 數據,測試接收和返回
curl -X POST -H "Content-Type: application/json" -d '{"name": "beifan", "age": 18}' http://127.0.0.1:8000/receive-json/
或用 Postman 等工具,發送?POST
?請求,Content-Type
?設為?application/json
,請求體填 JSON 內容(如?{"name": "beifan"}
?),查看響應是否返回相同 JSON 數據。
需求 2:接收表單參數,重定向到結果頁面
在?myapp/views.py
?中補充視圖:
from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import renderdef submit_form(request):# 處理 GET 請求,返回表單頁面(這里簡單用 HttpResponse 模擬,實際常用 render 加載 HTML 文件 )if request.method == 'GET': return HttpResponse('''<html><body><form method="POST" action="/submit-form/"><input type="text" name="username" placeholder="用戶名"><input type="submit" value="提交"></form></body></html>''')# 處理 POST 請求(表單提交 )elif request.method == 'POST': # 獲取表單里的 username 字段值,若不存在則為 Noneusername = request.POST.get('username') if username:# 重定向到結果頁面,可把參數拼接到 URL(簡單示例,也可用其他方式傳參 )return HttpResponseRedirect(f'/result/?username={username}') else:# 若用戶名為空,返回提示(實際可優化,比如留在表單頁提示填寫 )return HttpResponse("Username can't be empty", status=400) def result_page(request):# 從請求中獲取參數(重定向帶過來的 )username = request.GET.get('username') # 簡單返回結果頁面,展示用戶名(實際常用 render 加載 HTML 文件渲染 )return HttpResponse(f'Hello, {username}! Submission successful.')
?Django 里的JsonResponse
類
JsonResponse
是 Django 專門用來返回JSON 格式數據的工具類,長得就像一個 “帶 JSON 包裝紙的響應包裹” 📦,專門給前端(比如用 Axios 發請求的場景)送數據~
?
🧐 它長什么樣?(基本用法)
from django.http import JsonResponsedef my_view(request):# 準備要返回的數據(字典形式)data = {"status": "success", ? 狀態標識"message": "操作成功啦~", 💬 提示信息"result": {"name": "小明", "age": 18} 📊 具體數據}# 用JsonResponse包裝數據并返回return JsonResponse(data)
?
? 它的 “特殊技能”
自動打包成 JSON?🧰
不用你手動把字典轉成 JSON 字符串,JsonResponse
會自動幫你做這件事~ 上面的代碼返回給前端的會是這樣的 JSON:
{"status": "success", "message": "操作成功啦~", "result": {"name": "小明", "age": 18}}
自帶正確的 “身份標識”?🏷?
會自動在響應頭里加上Content-Type: application/json
,告訴前端:“我送的是 JSON 數據哦,快用 JSON 的方式解析我~”
可以定制行為???
如果想返回列表(不是字典),需要加safe=False
:
return JsonResponse([1, 2, 3], safe=False) 📋 列表數據專用
可以指定編碼:
return JsonResponse(data, json_dumps_params={'ensure_ascii': False}) 🌐 支持中文不轉義
?
🆚 和HttpResponse
的區別
HttpResponse
是 “萬能包裹” 📦,可以返回 HTML、文本等任何內容,但返回 JSON 需要手動處理(比如用json.dumps()
)。JsonResponse
是 “JSON 專用包裹” ?,專為返回 JSON 設計,更方便、更規范~
簡單說,JsonResponse
就像一個 “自動打包機”,把你的 Python 字典 / 列表快速變成前端能看懂的 JSON 數據,超適合前后端用 Ajax(比如 Axios)通信時使用哦~ 😎
json.loads()
?是把 “JSON 格式的字符串(像python的字典一樣)” 轉成 Python 數據
而?json.load()
?直接處理 “JSON 文件”
?📄 vs 📜