Django的请求和响应+template模板
🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!
亲爱的读者,
感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值,或者它解决了你一直以来的一个疑问,请给个赞吧 —— 这不仅是对我学习效果的认可,更是激励我继续前行的动力!
而且,如果你不想错过未来更多有趣的内容,记得点击关注哦!这样,每当有新文章发布时,你就能第一时间收到通知啦。让我们一起在这个充满无限可能的知识海洋中遨游,探索未知的世界吧!
最后,别忘了留下你的想法或问题在评论区。无论是赞美、建议还是疑问,我都非常期待听到你的声音。也许,正是你的那条评论,将开启一段全新的讨论旅程呢!
🌟 点赞、关注、留言 —— 三连走起,让我们共同成长,一起变得更优秀!
再次感谢每一位可爱的你,愿你在追求梦想的路上一帆风顺!
目录
🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!
接续上篇文章:《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 中安全、高效地实现文件上传和下载功能。