🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!
亲爱的读者,
感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值,或者它解决了你一直以来的一个疑问,请给个赞吧 —— 这不仅是对我学习效果的认可,更是激励我继续前行的动力!
而且,如果你不想错过未来更多有趣的内容,记得点击关注哦!这样,每当有新文章发布时,你就能第一时间收到通知啦。让我们一起在这个充满无限可能的知识海洋中遨游,探索未知的世界吧!
最后,别忘了留下你的想法或问题在评论区。无论是赞美、建议还是疑问,我都非常期待听到你的声音。也许,正是你的那条评论,将开启一段全新的讨论旅程呢!
🌟 点赞、关注、留言 —— 三连走起,让我们共同成长,一起变得更优秀!
再次感谢每一位可爱的你,愿你在追求梦想的路上一帆风顺!
目录
接续上篇文章:《Django 实战揭秘:从项目搭建到多页面开发的超详细指南》一_django 一个app创建多个页面-CSDN博客
3.在Django中,如何使用请求和响应来实现文件上传和下载?
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:
将下载好的文件放置于项目工程文件夹中。
温馨提示: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) # 获取参数,默认值为1 return 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): # 重定向到新的URL return 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 response else: 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 response return 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 response return 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 response except 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 中安全、高效地实现文件上传和下载功能。