🌟 如果這篇文章觸動了你的心弦,請不要吝嗇你的支持!
親愛的讀者,
感謝你花時間閱讀這篇分享。希望這里的每一個字都能為你帶來啟發或是讓你會心一笑。如果你覺得這篇文章有價值,或者它解決了你一直以來的一個疑問,請給個贊吧 —— 這不僅是對我學習效果的認可,更是激勵我繼續前行的動力!
而且,如果你不想錯過未來更多有趣的內容,記得點擊關注哦!這樣,每當有新文章發布時,你就能第一時間收到通知啦。讓我們一起在這個充滿無限可能的知識海洋中遨游,探索未知的世界吧!
最后,別忘了留下你的想法或問題在評論區。無論是贊美、建議還是疑問,我都非常期待聽到你的聲音。也許,正是你的那條評論,將開啟一段全新的討論旅程呢!
🌟 點贊、關注、留言 —— 三連走起,讓我們共同成長,一起變得更優秀!
再次感謝每一位可愛的你,愿你在追求夢想的路上一帆風順!
目錄
🌟 如果這篇文章觸動了你的心弦,請不要吝嗇你的支持!
接續上篇文章:???????《Django 實戰揭秘:從項目搭建到多頁面開發的超詳細指南》一_django 一個app創建多個頁面-CSDN博客
4.4.4template模版
4.4.5靜態文件
功能側重
應用場景
4.4.6模板語法
4.4.7 請求和響應
1. def something(request)
請求相關:
響應相關:
關于重定向的原理:
2. csrf_token
在表單中使用 csrf_token
AJAX 請求中的 CSRF 處理
視圖中處理 CSRF 驗證
豁免 CSRF 保護(不推薦在 POST 請求中使用)
CSRF 工作原理:
3.在Django中,如何使用請求和響應來實現文件上傳和下載?
一、文件上傳功能
二、文件下載功能
三、優化方案
四、配置 settings.py
五、關鍵知識點總結
4.4.4template模版
返回html的話需要將視圖py文件中的視圖函數→返回:
render(request,"user_list.html")
"user_list.html"在哪里尋找呢?
在templates目錄文件下的.html文件中找。更為詳細的說就是:在settings.py文件中注冊過的app,依照該注冊app的順序進行相應html文件的查找!
views.py文件: from django.shortcuts import render,HttpResponse def user_list(Request):return render(Request,"user_list.html")user_list.html:<h1>用戶列表</h1>
效果圖:
注意:默認情況下只會在自己注冊的app中尋找相應的html文件。
如果在根目錄下有templates文件夾,那么肯定是配置了settings.py文件中的屬性:DIR[ 有內容]
如果里面有內容的話,那個尋找模版就是從根目錄開始尋找!
4.4.5靜態文件
注意:必須在app目錄下創建一個名為static的目錄下放置靜態資源(圖片等)
創建結構如圖所示:
步驟:
-
在app目錄下創建static文件夾:如上所示
-
在html模板中:
-
需要先引入:{% load static%}
-
代碼如下所示:
{% load static %} ? #關鍵點1 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.css' %}"> #關鍵點2:路徑 </head> <body> <h1>用戶列表</h1> <input type="text" class="btn btn-primary" value="新建"/> <img src="{% static 'img/1.png' %}" alt=""> <script src="{% static 'js/jquery-3.6.0.min.js' %}"></script> <script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.js' %}"></script> </body> </html>
引入css和js:
Download jQuery | jQuery
Download · Bootstrap v5.3
將下載好的文件放置于項目工程文件夾中。
溫馨提示:Bootstrap中也有js文件夾,那么和jQuery有什么區別呢?
Query 和 Bootstrap 中的 js 文件在功能上有以下區別:
功能側重
-
jQuery
:是 JavaScript 函數庫,重點在簡化 JavaScript 操作。
-
DOM 操作:提供強大選擇器,像
$('id')
$('class')
$('tag')
等,能便捷選取并操作 HTML 元素,比如增刪改查節點 、獲取或設置屬性值 。例如$('#elementId').text('新文本')
可修改指定id
元素文本內容。 -
事件處理:能輕松綁定事件,如
click
、mouseover
、submit
等。$('button').click(function(){ /* 點擊按鈕執行代碼 */ });
可實現按鈕點擊響應。 -
動畫效果:方便創建元素動畫,像淡入淡出、滑動、漸隱漸現等。
$('#box').fadeIn('slow');
能讓指定元素緩慢淡入顯示。 -
Ajax 交互:簡化與服務器的數據交互,可異步獲取數據并更新頁面。
$.ajax({ url: 'data.php', success: function(data){ /* 處理返回數據 */ } });
能從服務器獲取數據。
-
-
Bootstrap 的 js 文件
:屬于前端框架的一部分,基于 jQuery 開發(Bootstrap 5 開始不強制依賴 ),主要為組件賦予交互功能。
-
組件交互:為按鈕、模態框、導航欄、標簽頁等組件提供交互行為。如點擊按鈕彈出模態框、切換標簽頁等。
-
響應式行為:配合 CSS 實現響應式布局相關交互,如導航欄在不同屏幕尺寸下的折疊、展開等。
-
應用場景
-
jQuery:適用于各類需要操作 DOM、處理事件、實現動畫或 Ajax 交互的場景,開發靈活,可根據需求編寫自定義功能。
-
Bootstrap 的 js 文件:用于快速構建響應式、具備統一風格的網站或應用,利用其現成組件快速搭建頁面交互,提升開發效率。
最后經過更新后的代碼:
{% load static %} ? <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static 'plugins/bootstrap5.3/css/bootstrap.css' %}"> </head> <body> <h1>用戶列表</h1> <input type="text" class="btn btn-primary" value="新建"/> <img src="{% static 'img/1.jpg' %}" alt=""> <script src="{% static 'js/jquery-3.7.1.min.js' %}"></script> <script src="{% static 'plugins/bootstrap5.3/js/bootstrap.js' %}"></script> </body> </html>
結果如下所示:
-
-
4.4.6模板語法
本質上:就是占位符
首先創建了一個HTML文件:user_lh.html文件
{% load static %} ? <!DOCTYPE html> <html lang="en"> <head></head> <body> <h1>模版語法</h1> <div>{{hkc}}</div> <div>{{roles}}</div> <div>{{roles.0}}</div> <div>{{roles.1}}</div> <div>{{roles.2}}</div> ? </body> </html>
然后創建對應的視圖函數:
def user_lh(Request):name="行手動閥"roles=["老板","員工","領導"]return render (Request,"user_lh.html",{"hkc":name,"roles":roles})
實現效果:
4.4.7 請求和響應
1. def something(request)
request
是一個封裝了用戶所有請求數據的對象,以下是其常用屬性和方法的示例:
請求相關:
request.method (獲取請求方式)
def handle_request(request):if request.method == 'GET':return HttpResponse('這是GET請求')elif request.method == 'POST':return HttpResponse('這是POST請求')else:return HttpResponse(f'不支持的請求方式: {request.method}')
request.GET (通過 URL 傳遞參數)
# URL示例: /search/?keyword=python&page=2 def search(request):keyword = request.GET.get('keyword', '') ?# 獲取參數,默認值為空字符串page = request.GET.get('page', 1) ? ? ? ?# 獲取參數,默認值為1return HttpResponse(f'搜索關鍵詞: {keyword}, 頁碼: {page}')
request.POST (在請求體中提交數據)
# 處理表單提交 def login(request):if request.method == 'POST':username = request.POST.get('username')password = request.POST.get('password')if username == 'admin' and password == '123456':return HttpResponse('登錄成功')else:return HttpResponse('用戶名或密碼錯誤')# GET請求返回登錄表單return render(request, 'login.html')
響應相關:
內容字符串返回瀏覽器 (return HttpResponse)
def hello(request):return HttpResponse('Hello, World!')
讀取 HTML 內容并渲染 (return render)
def home(request):context = {'title': '首頁','welcome': '歡迎訪問我的網站'}return render(request, 'home.html', context)
返回網址跳轉 (redirect)
from django.shortcuts import redirect ? def old_url(request):# 重定向到新的URLreturn redirect('/new-url/') ?# 瀏覽器會收到302狀態碼并自動跳轉 ? def permanent_redirect(request):# 永久重定向(301)return redirect('/permanent-new-url/', permanent=True) ? def redirect_with_params(request):# 帶參數的重定向return redirect('user_profile', user_id=123) ?# 假設使用了命名URL
關于重定向的原理:
-
Django 的
redirect
函數會返回一個 HttpResponseRedirect 對象(狀態碼 302/301) -
瀏覽器收到這個響應后,會自動發送新的請求到指定的 URL
-
302 表示臨時重定向,搜索引擎不會更新索引
-
301 表示永久重定向,搜索引擎會更新索引
2. csrf_token
CSRF(跨站請求偽造)保護是 Django 提供的安全機制,用于防止惡意網站偽裝成合法請求。
示例:
在表單中使用 csrf_token
<!-- login.html --> <form method="post">{% csrf_token %}<label for="username">用戶名:</label><input type="text" id="username" name="username"><br><label for="password">密碼:</label><input type="password" id="password" name="password"><br><button type="submit">登錄</button> </form>
AJAX 請求中的 CSRF 處理
<!-- 模板中添加CSRF令牌 --> <script>function getCookie(name) {let cookieValue = null;if (document.cookie && document.cookie !== '') {const cookies = document.cookie.split(';');for (let i = 0; i < cookies.length; i++) {const cookie = cookies[i].trim();if (cookie.substring(0, name.length + 1) === (name + '=')) {cookieValue = decodeURIComponent(cookie.substring(name.length + 1));break;}}}return cookieValue;}// 獲取CSRF令牌const csrftoken = getCookie('csrftoken');// 發送AJAX請求時添加CSRF頭function sendAjaxRequest() {fetch('/api/submit/', {method: 'POST',headers: {'Content-Type': 'application/json','X-CSRFToken': csrftoken},body: JSON.stringify({data: 'example'})}).then(response => response.json()).then(data => console.log(data));} </script>
視圖中處理 CSRF 驗證
from django.views.decorators.csrf import csrf_protect ? @csrf_protect ?# 顯式啟用CSRF保護 def process_form(request):if request.method == 'POST':# 處理表單數據return HttpResponse('表單提交成功')else:return render(request, 'form.html')
豁免 CSRF 保護(不推薦在 POST 請求中使用)
from django.views.decorators.csrf import csrf_exempt ? @csrf_exempt ?# 禁用CSRF保護 def api_endpoint(request):if request.method == 'POST':# 處理API請求return JsonResponse({'status': 'success'})else:return JsonResponse({'error': 'Method not allowed'}, status=405)
CSRF 工作原理:
-
Django 在渲染模板時,會在
<form>
標簽中插入一個隱藏的csrfmiddlewaretoken
字段 -
當表單提交時,這個 token 會隨請求一起發送到服務器
-
Django 中間件會驗證請求中的 token 與用戶會話中的 token 是否一致
-
對于 AJAX 請求,需要從 cookie 中獲取 CSRF 令牌并添加到請求頭中(
X-CSRFToken
)
3.在Django中,如何使用請求和響應來實現文件上傳和下載?
在 Django 中實現文件上傳和下載功能需要結合請求處理和響應返回,下面是詳細的實現方法:
一、文件上傳功能
-
創建表單模板 (
upload_form.html
)
<form method="POST" enctype="multipart/form-data">{% csrf_token %}<input type="file" name="myfile"><button type="submit">上傳文件</button> </form>
-
視圖函數處理上傳 (
views.py
)
from django.shortcuts import render from django.http import HttpResponse ? def upload_file(request):if request.method == 'POST' and request.FILES.get('myfile'):# 獲取上傳的文件對象uploaded_file = request.FILES['myfile']# 保存文件到服務器with open(f'media/{uploaded_file.name}', 'wb+') as destination:for chunk in uploaded_file.chunks():destination.write(chunk)return HttpResponse('文件上傳成功!')return render(request, 'upload_form.html')
-
關鍵要點:
-
表單設置:必須使用
method="POST"
和enctype="multipart/form-data"
-
文件對象:通過
request.FILES['字段名']
獲取上傳的文件 -
文件保存:推薦使用
chunks()
方法分塊寫入,避免大文件內存溢出
二、文件下載功能
-
視圖函數返回文件 (
views.py
)
from django.http import FileResponse, HttpResponseNotFound import os ? def download_file(request):file_path = 'media/example.pdf' ?# 文件在服務器上的路徑if os.path.exists(file_path):# 打開文件并返回響應response = FileResponse(open(file_path, 'rb'))response['Content-Type'] = 'application/octet-stream' ?# 二進制流response['Content-Disposition'] = 'attachment; filename="example.pdf"'return responseelse:return HttpResponseNotFound('文件不存在!')
-
動態文件名下載
def dynamic_download(request):filename = request.GET.get('filename')file_path = f'media/{filename}'if os.path.exists(file_path):response = FileResponse(open(file_path, 'rb'))response['Content-Disposition'] = f'attachment; filename="{filename}"'return responsereturn HttpResponseNotFound('文件不存在!')
-
關鍵要點:
-
響應類型:使用
FileResponse
或HttpResponse
返回文件內容 -
Content-Type
:常見值包括:
-
application/octet-stream
(通用二進制文件) -
application/pdf
(PDF 文件) -
image/jpeg
(JPEG 圖片)
-
-
Content-Disposition:
attachment
強制下載,filename
指定下載后的文件名
三、優化方案
-
使用 Django 的
FileSystemStorage
from django.core.files.storage import FileSystemStorage ? def upload_file(request):if request.method == 'POST' and request.FILES.get('myfile'):myfile = request.FILES['myfile']fs = FileSystemStorage()filename = fs.save(myfile.name, myfile) ?# 自動處理重名文件file_url = fs.url(filename)return HttpResponse(f'文件已上傳: <a href="{file_url}">{filename}</a>')return render(request, 'upload_form.html')
-
安全下載(避免路徑遍歷攻擊)
from django.conf import settings from django.utils.encoding import smart_str ? def secure_download(request):filename = request.GET.get('filename')valid_files = {'example.pdf', 'data.csv'} ?# 允許下載的文件白名單if filename in valid_files:file_path = os.path.join(settings.MEDIA_ROOT, filename)response = FileResponse(open(file_path, 'rb'))response['Content-Disposition'] = f'attachment; filename="{smart_str(filename)}"'return responsereturn HttpResponseForbidden('禁止訪問該文件!')
-
大文件流式下載
def stream_download(request):file_path = 'media/large_file.zip'try:response = FileResponse(open(file_path, 'rb'), as_attachment=True)response['Content-Disposition'] = 'attachment; filename="large_file.zip"'return responseexcept Exception:return HttpResponseServerError('下載失敗,請稍后再試!')
四、配置 settings.py
# settings.py MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') ? # urls.py from django.conf import settings from django.conf.urls.static import static ? urlpatterns = [# 其他URL配置... ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
五、關鍵知識點總結
-
文件上傳:
-
表單需設置
enctype="multipart/form-data"
-
通過
request.FILES
獲取文件對象 -
使用
FileSystemStorage
簡化文件管理
-
-
文件下載:
-
使用
FileResponse
返回二進制文件 -
設置
Content-Disposition
控制下載行為 -
對用戶提供的文件名進行嚴格驗證,防止路徑遍歷攻擊
-
-
安全注意事項:
-
限制上傳文件大小(通過
FILE_UPLOAD_MAX_MEMORY_SIZE
) -
驗證上傳文件類型(擴展名、MIME 類型)
-
避免直接暴露服務器文件路徑
-
通過以上方法,你可以在 Django 中安全、高效地實現文件上傳和下載功能。