Django 视图函数中的 `response` 对象及类型扩写

Django 视图函数中的 response 对象及类型扩写

在 Django 中,视图函数不仅负责处理请求,还负责生成响应。响应可以是以多种格式返回给客户端的数据,包括 HTML 页面、重定向、JSON 数据、文件等。以下是关于 Django 中几种常见响应类型的详细扩写。

HttpResponse

HttpResponse 是 Django 中最基本的响应类型,用于返回一个纯文本或 HTML 内容的响应。

python 复制代码
from django.http import HttpResponse

def my_view(request):
    # 返回一个简单的文本响应
    return HttpResponse("Hello, World!")

    # 返回一个 HTML 内容的响应
    # html_content = "<html><body><h1>Hello, World!</h1></body></html>"
    # return HttpResponse(html_content, content_type="text/html")

你还可以设置响应的状态码和字符集。

python 复制代码
# 返回一个自定义状态码的响应
return HttpResponse("Not Found", status=404)

# 返回一个指定字符集的响应
return HttpResponse("Hello, World!", charset="utf-8")
render 函数

render 函数是 Django 的一个快捷函数,用于渲染一个模板并返回一个 HttpResponse 对象。

python 复制代码
from django.shortcuts import render

def my_template_view(request):
    # 传递一个字典给模板
    context = {'message': 'Hello, Template!'}
    # 渲染模板并返回响应
    return render(request, 'my_template.html', context)

模板文件 my_template.html 应该位于你配置的模板目录中,并且可以这样使用传递的上下文数据:

html 复制代码
<!DOCTYPE html>
<html>
<head>
    <title>My Template</title>
</head>
<body>
    <h1>{{ message }}</h1>
</body>
</html>
redirect 函数 / HttpResponseRedirect

redirect 函数用于生成一个重定向响应。它会向客户端返回一个 302(临时重定向)或 301(永久重定向)状态码,以及一个新的 URL。

python 复制代码
from django.shortcuts import redirect

def my_redirect_view(request):
    # 重定向到一个新的 URL
    return redirect('/new-url/')

    # 使用命名 URL 模式重定向,并传递参数
    # return redirect('named_url_pattern', arg1=value1, arg2=value2)

    # 永久重定向
    # return redirect('/new-url/', permanent=True)
JsonResponse

JsonResponse 用于返回 JSON 格式的响应。它自动设置 Content-Typeapplication/json

python 复制代码
from django.http import JsonResponse

def my_json_view(request):
    data = {'message': 'Hello, JSON!'}
    return JsonResponse(data)

    # 如果需要自定义 JSON 序列化行为,可以传递 encoder 参数
    # from django.core.serializers.json import DjangoJSONEncoder
    # class MyEncoder(DjangoJSONEncoder):
    #     # 自定义序列化行为
    #     pass
    # return JsonResponse(data, encoder=MyEncoder)

    # 如果需要返回非字典类型的数据,可以将 safe 设置为 False
    # data = ['Hello', 'World']
    # return JsonResponse(data, safe=False)
FileResponse

FileResponse 用于返回文件内容的响应。它接受一个文件对象或文件路径,并自动设置适当的 Content-TypeContent-Disposition 头。

python 复制代码
from django.http import FileResponse
import os

def my_file_view(request):
    # 假设文件位于项目的 media 目录下
    file_path = os.path.join(BASE_DIR, 'media', 'myfile.txt')
    # 打开文件并创建 FileResponse
    with open(file_path, 'rb') as file:
        response = FileResponse(file)
        # 可以设置 Content-Disposition 为 attachment 以提示浏览器下载文件
        # response['Content-Disposition'] = 'attachment; filename="myfile.txt"'
        return response

POST 提交 403 禁止访问 的解决方案

在 Django 中,为了防止跨站请求伪造(CSRF)攻击,默认情况下会对所有使用 POSTPUTPATCHDELETE 等方法的表单进行 CSRF 保护。如果你的表单或 AJAX 请求遇到了 403 禁止访问的错误,通常是因为缺少了 CSRF 令牌。

  • 方式一 :在表单中添加 {% csrf_token %} 标签。
html 复制代码
<form method="post">
    {% csrf_token %}
    <!-- 表单的其他字段 -->
    <button type="submit">Submit</button>
</form>
  • 方式二 :在视图函数上使用 @csrf_exempt 装饰器来免除 CSRF 保护(不推荐,除非在特定情况下确实需要)。
python 复制代码
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def my_exempt_view(request):
    # 处理请求
    pass
  • 方式三 :在 settings.py 中注释掉 CsrfViewMiddleware 中间件(这是非常不安全的做法,不推荐)。
python 复制代码
# MIDDLEWARE = [
#     # ...
#     'django.middleware.csrf.CsrfViewMiddleware',
#     # ...
# ]

通常,推荐使用第一种方式,即在表单中添加 {% csrf_token %} 标签,以确保 CSRF 保护的有效性。对于 AJAX 请求,你可以在发送请求时包含 CSRF 令牌,通常是通过在请求头中添加 X-CSRFToken

相关推荐
小陈工1 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花6 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸6 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql
D4c-lovetrain6 小时前
linux个人心得22 (mysql)
数据库·mysql
阿里小阿希6 小时前
CentOS7 PostgreSQL 9.2 升级到 15 完整教程
数据库·postgresql
荒川之神6 小时前
Oracle 数据仓库雪花模型设计(完整实战方案)
数据库·数据仓库·oracle
做个文艺程序员6 小时前
MySQL安全加固十大硬核操作
数据库·mysql·安全
不吃香菜学java7 小时前
Redis简单应用
数据库·spring boot·tomcat·maven
一个天蝎座 白勺 程序猿7 小时前
Apache IoTDB(15):IoTDB查询写回(INTO子句)深度解析——从语法到实战的ETL全链路指南
数据库·apache·etl·iotdb
不知名的老吴7 小时前
Redis的延迟瓶颈:TCP栈开销无法避免
数据库·redis·缓存