Django的请求和响应+template模板

🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!

亲爱的读者,

感谢你花时间阅读这篇分享。希望这里的每一个字都能为你带来启发或是让你会心一笑。如果你觉得这篇文章有价值,或者它解决了你一直以来的一个疑问,请给个赞吧 ------ 这不仅是对我学习效果的认可,更是激励我继续前行的动力!

而且,如果你不想错过未来更多有趣的内容,记得点击关注哦!这样,每当有新文章发布时,你就能第一时间收到通知啦。让我们一起在这个充满无限可能的知识海洋中遨游,探索未知的世界吧!

最后,别忘了留下你的想法或问题在评论区。无论是赞美、建议还是疑问,我都非常期待听到你的声音。也许,正是你的那条评论,将开启一段全新的讨论旅程呢!

🌟 点赞、关注、留言 ------ 三连走起,让我们共同成长,一起变得更优秀!

再次感谢每一位可爱的你,愿你在追求梦想的路上一帆风顺!

目录

[🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!](#🌟 如果这篇文章触动了你的心弦,请不要吝啬你的支持!)

[接续上篇文章:​​​​​​​《Django 实战揭秘:从项目搭建到多页面开发的超详细指南》一_django 一个app创建多个页面-CSDN博客](#接续上篇文章:《Django 实战揭秘:从项目搭建到多页面开发的超详细指南》一_django 一个app创建多个页面-CSDN博客)

4.4.4template模版

4.4.5静态文件

功能侧重

应用场景

4.4.6模板语法

[4.4.7 请求和响应](#4.4.7 请求和响应)

[1. def something(request)](#1. def something(request))

请求相关:

响应相关:

关于重定向的原理:

[2. csrf_token](#2. csrf_token)

[在表单中使用 csrf_token](#在表单中使用 csrf_token)

[AJAX 请求中的 CSRF 处理](#AJAX 请求中的 CSRF 处理)

[视图中处理 CSRF 验证](#视图中处理 CSRF 验证)

[豁免 CSRF 保护(不推荐在 POST 请求中使用)](#豁免 CSRF 保护(不推荐在 POST 请求中使用))

[CSRF 工作原理:](#CSRF 工作原理:)

3.在Django中,如何使用请求和响应来实现文件上传和下载?

一、文件上传功能

二、文件下载功能

三、优化方案

[四、配置 settings.py](#四、配置 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的目录下放置静态资源(图片等)

创建结构如图所示:

步骤:

  1. 在app目录下创建static文件夹:如上所示

  2. 在html模板中:

    1. 需要先引入:{% load static%}

    2. 代码如下所示:

      复制代码
      {% 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元素文本内容。

        • 事件处理 :能轻松绑定事件,如clickmouseoversubmit等。$('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 工作原理:
  1. Django 在渲染模板时,会在<form>标签中插入一个隐藏的csrfmiddlewaretoken字段

  2. 当表单提交时,这个 token 会随请求一起发送到服务器

  3. Django 中间件会验证请求中的 token 与用户会话中的 token 是否一致

  4. 对于 AJAX 请求,需要从 cookie 中获取 CSRF 令牌并添加到请求头中(X-CSRFToken

3.在Django中,如何使用请求和响应来实现文件上传和下载?

在 Django 中实现文件上传和下载功能需要结合请求处理和响应返回,下面是详细的实现方法:

一、文件上传功能
  1. 创建表单模板 (upload_form.html)
复制代码
<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="myfile">
    <button type="submit">上传文件</button>
</form>
  1. 视图函数处理上传 (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')
  1. 关键要点:
  • 表单设置 :必须使用 method="POST"enctype="multipart/form-data"

  • 文件对象 :通过 request.FILES['字段名'] 获取上传的文件

  • 文件保存 :推荐使用 chunks() 方法分块写入,避免大文件内存溢出

二、文件下载功能
  1. 视图函数返回文件 (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('文件不存在!')
  1. 动态文件名下载
复制代码
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('文件不存在!')
  1. 关键要点:
  • 响应类型 :使用 FileResponseHttpResponse 返回文件内容

  • Content-Type

    :常见值包括:

    • application/octet-stream(通用二进制文件)

    • application/pdf(PDF 文件)

    • image/jpeg(JPEG 图片)

  • Content-Dispositionattachment 强制下载,filename 指定下载后的文件名

三、优化方案
  1. 使用 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')
  1. 安全下载(避免路径遍历攻击)
复制代码
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('禁止访问该文件!')
  1. 大文件流式下载
复制代码
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)
五、关键知识点总结
  1. 文件上传

    • 表单需设置 enctype="multipart/form-data"

    • 通过 request.FILES 获取文件对象

    • 使用 FileSystemStorage 简化文件管理

  2. 文件下载

    • 使用 FileResponse 返回二进制文件

    • 设置 Content-Disposition 控制下载行为

    • 对用户提供的文件名进行严格验证,防止路径遍历攻击

  3. 安全注意事项

    • 限制上传文件大小(通过 FILE_UPLOAD_MAX_MEMORY_SIZE

    • 验证上传文件类型(扩展名、MIME 类型)

    • 避免直接暴露服务器文件路径

通过以上方法,你可以在 Django 中安全、高效地实现文件上传和下载功能。

相关推荐
金玉满堂@bj5 分钟前
PyCharm 中 Python 解释器的添加选项及作用
ide·python·pycharm
程序员三藏9 分钟前
如何使用Pytest进行测试?
自动化测试·软件测试·python·测试工具·职场和发展·测试用例·pytest
随心点儿1 小时前
使用python 将多个docx文件合并为一个word
开发语言·python·多个word合并为一个
不学无术の码农1 小时前
《Effective Python》第十三章 测试与调试——使用 Mock 测试具有复杂依赖的代码
开发语言·python
sleepybear11131 小时前
在Ubuntu上从零开始编译并运行Home Assistant源码并集成HACS与小米开源的Ha Xiaomi Home
python·智能家居·小米·home assistant·米家·ha xiaomi home
纪伊路上盛名在1 小时前
(鱼书)深度学习入门1:python入门
人工智能·python·深度学习
夏末蝉未鸣011 小时前
python transformers笔记(TrainingArguments类)
python·自然语言处理·transformer
德育处主任Pro1 小时前
「py数据分析」04如何将 Python 爬取的数据保存为 CSV 文件
数据库·python·数据分析
咸鱼鲸2 小时前
【PyTorch】PyTorch中数据准备工作(AI生成)
人工智能·pytorch·python
遇见你很高兴2 小时前
Pycharm中体验通义灵码来AI辅助编程
python