
URL 分发机制(URLconf)
path() 基础使用
- path("路由/", 视图函数, name="命名")
- 支持静态和动态参数(如
<int:id>
)
示例:
blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'), # 主页
path('post/<int:id>/', views.post_detail, name='post_detail'), # 动态路径参数
]
在 Django 的 URL 配置中,name='post_detail'
是为 URL 模式命名的,这个命名在 Django 中的作用是 1、解耦 URL 路径和代码逻辑,避免硬编码。2、方便动态生成 URL,提高代码可维护性。常用在:
1、URL 反向解析(Reverse URL Lookup)
允许你在模板或 Python 代码中动态生成 URL,而不用硬编码 URL 路径。
<!-- html 文件,在模板中使用 -->
<a href="{% url 'post_detail' id=post.id %}">查看详情</a>
# 在 Python 代码中使用
from django.urls import reverse
url = reverse('post_detail', kwargs={'id': 1}) # 返回类似 '/post/1/'
如果以后 URL 模式改变(比如从 post/<int:id>/
改成 articles/<int:id>/
),你只需要修改 urls.py
,而不用修改所有模板和视图中的硬编码 URL。
2、在重定向(Redirect)中使用
在视图函数中可以使用命名的 URL 进行重定向:
from django.shortcuts import redirect
return redirect('post_detail', id=5) # 重定向到 '/post/5/'
views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("欢迎来到博客首页")
def post_detail(request, id):
return HttpResponse(f"您正在查看第 {id} 篇文章")
结果展示:


re_path()
(旧版叫 url()
)正则表达式路由
- 更灵活的路径匹配(例如:年份、slug)
示例:
urls.py
from django.urls import re_path
from . import views
urlpatterns += [
re_path(r'^archive/(?P<year>[0-9]{4})/$', views.archive_by_year, name='archive_by_year'),
]
views.py
def archive_by_year(request, year):
return HttpResponse(f"{year} 年的归档")
r'^archive/(?P<year>[0-9]{4})/$' 匹配讲解:
r
表示这是一个原始字符串(raw string),避免 Python 对反斜杠的特殊处理^
表示匹配字符串的开始archive/
是字面匹配,必须精确匹配这部分(?P<year>[0-9]{4})
是命名捕获组:?P<year>
表示将捕获的内容命名为 "year",这会要求views.py中必须接受传入的“year”参数[0-9]{4}
表示匹配恰好 4 个数字字符(0-9)
/
是字面匹配的斜杠$
表示匹配字符串的结束

include() 模块化拆分
主项目调用子 app 的 urls.py
项目根目录的 urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')), # 引入 blog 子应用的路由
]
命名路由 + 反向解析
什么是命名路由(name 参数)
Django 中的路由是通过 path()
来注册的,比如:
from django.urls import path
from . import views
urlpatterns = [
path('posts/<int:id>/', views.post_detail, name='post_detail'), # 👈 这里的 name 参数就是“命名路由”
]
这段代码的意思是:
- 访问 URL
/posts/3/
会执行views.post_detail(request, id=3)
- 并且这个路由有个别名叫做
'post_detail'
有了这个 name,我们就可以用名字反向生成 URL 地址,这叫做“反向解析”。
什么是反向解析(reverse 和 {% url %})
1、在视图函数里:用 reverse()
比如你想在视图函数中跳转到帖子详情页(比如 /posts/3/
):
from django.urls import reverse
from django.shortcuts import redirect
def go_to_post(request):
url = reverse('post_detail', kwargs={'id': 3}) # 👈 根据路由名称和参数,反向生成 URL
return redirect(url)
'post_detail'
是路由名称kwargs={'id': 3}
表示这个 URL 中的<int:id>
是 3reverse()
返回的就是/posts/3/
- 然后
redirect()
会跳转过去
2、在模板中:用 {% url %}
标签
如果你想在页面中放一个跳转链接:
<a href="{% url 'post_detail' id=3 %}">查看第三篇文章</a>
这段模板代码会被渲染成:
<a href="/posts/3/">查看第三篇文章</a>
方便之处:不需要自己拼接 URL,只要写清楚名字和参数就好
实战 demo:
blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('posts/<int:id>/', views.post_detail, name='post_detail'), # 命名路由
path('go/', views.go_to_post), # 跳转用的视图
path('', views.post_list, name='post_list'), # 首页文章列表
]
blog/views.py
from django.shortcuts import render, redirect
from django.urls import reverse
from django.http import HttpResponse
def post_detail(request, id):
return HttpResponse(f"你正在查看第 {id} 篇文章")
def go_to_post(request):
# 模拟跳转到第 3 篇文章
url = reverse('post_detail', kwargs={'id': 3})
return redirect(url)
def post_list(request):
return render(request, 'blog/post_list.html')
templates/blog/post_list.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>文章列表</title>
</head>
<body>
<h1>博客文章列表</h1>
<ul>
<li><a href="{% url 'post_detail' id=1 %}">查看第 1 篇文章</a></li>
<li><a href="{% url 'post_detail' id=2 %}">查看第 2 篇文章</a></li>
<li><a href="{% url 'post_detail' id=3 %}">查看第 3 篇文章</a></li>
</ul>
</body>
</html>
结果演示:
访问路径为/go/,使用 reverse()
反向解析后,跳转到 /posts/3/

/posts/3/ 会显示“你正在查看第 3 篇文章”
/
目录下渲染模板,用 {% url %}
生成多个跳转链接

视图函数与 HTTP 响应
HttpResponse
最基本的返回
from django.http import HttpResponse
def simple_response(request):
return HttpResponse("这是一个简单响应")
render()
知识点:
- 渲染模板 + 传值
render() 是什么?它做了什么?
定义:
render(request, template_name, context=None)
render()
是 Django 提供的快捷函数,用于:
- 加载指定模板(HTML 文件)
- 使用
context
上下文中的变量进行渲染 - 返回一个包含渲染结果的
HttpResponse
底层其实这样
from django.template import loader
from django.http import HttpResponse
template = loader.get_template("blog/index.html")
html = template.render({"posts": posts}, request)
return HttpResponse(html)
作用流程:
- 找到模板文件(路径是:
templates/blog/index.html
) - 把视图中传入的
posts
列表交给模板 - 模板用
{% for post in posts %}
遍历并展示 - 最后返回一个完整 HTML 页面给浏览器
完整示例:博客首页
models.py(定义数据模型)
# blog/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
def __str__(self):
return self.title
views.py(视图函数)
# blog/views.py
from django.shortcuts import render
from .models import Post
def index(request):
# 获取所有文章
posts = Post.objects.all()
# 渲染模板并传入上下文变量
return render(request, "blog/index.html", {"posts": posts})
urls.py(路由系统)
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="post_index"), # 命名路由
]
# 项目根目录 urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include("blog.urls")), # 引入 blog 应用的路由
]
templates/blog/index.html
<!-- templates/blog/index.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>博客首页</title>
</head>
<body>
<h1>所有文章</h1>
<ul>
{% for post in posts %}
<li>{{ post.title }}</li>
{% empty %}
<li>暂无文章</li>
{% endfor %}
</ul>
</body>
</html>
用户访问 /posts/ → URL 交给 views.index → views.py 获取所有文章 Post.objects.all() → render() 渲染 blog/index.html → 模板中遍历 posts 显示标题 → 浏览器收到完整 HTML 页面
扩展:如果你准备实现文章详情页,那就该同时:
在 blog/urls.py
添加对应路由:
# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path("", views.index, name="post_index"),
path("<int:id>/", views.detail, name="post_detail"), # 加这个
]
在 blog/views.py
中添加 detail
视图:
# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def detail(request, id):
post = get_object_or_404(Post, id=id)
return render(request, "blog/detail.html", {"post": post})
新建模板 templates/blog/detail.html
<!-- templates/blog/detail.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ post.title }}</title>
</head>
<body>
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
<a href="{% url 'post_index' %}">返回首页</a>
</body>
</html>
修改 templates/blog/index.html
<!DOCTYPE html>
<html>
<head>
<title>所有文章</title>
</head>
<body>
<h1>所有文章</h1>
<ul>
{% for post in posts %}
<li>
<!-- 每个文章标题链接到详情页 -->
<a href="{% url 'post_detail' id=post.id %}">{{ post.title }}</a>
</li>
{% empty %}
<li>暂无文章</li>
{% endfor %}
</ul>
</body>
</html>
完成这些之后,你访问 /blog/
时看到的首页文章列表,每个标题就能点进去,跳转到对应文章的详情页了。

获取请求参数与body处理
URL 动态路径参数
什么是“动态路径参数”?
就是 URL 地址中直接嵌入一个“值”,比如:
/post/1/ 表示访问 ID 为 1 的文章
/post/23/ 表示访问 ID 为 23 的文章
Django 如何实现?
urls.py 这样写:
path('post/<int:id>/', views.post_detail, name='post_detail')
<int:id>
表示这是一个整数类型的参数,叫做 id
。
当用户访问 /post/3/
时,Django 会自动把 3
提取出来,传给 views.post_detail
函数。
views.py
中处理:
from django.http import HttpResponse
from .models import Post # 假设你有这个模型
def post_detail(request, id):
post = Post.objects.get(id=id) # 根据 id 找文章
return HttpResponse(f"文章:{post.title}")
访问测试:
你访问 /post/3/
,它会去数据库里查 ID=3 的文章,并返回:

复杂的 URL 路由动态路径参数推荐使用关键字参数
URL 正则表达式配置
假设我们仍然在博客应用的上下文中,有一个能够处理动态路径参数 id
的文章详情页,使用 re_path()
。我们将允许 id
参数为数字,且可以指定文章的 slug(短语)如: /post/1/python-introduction/
。
首先,在 urls.py
中使用 re_path()
:
# blog/urls.py
from django.urls import re_path
from . import views
urlpatterns = [
re_path(r'^post/(?P<id>\d+)/(?P<slug>[\w-]+)/$', views.post_detail, name='post_detail'),
]
(?P<id>\d+)
是一个命名捕获组,它捕获数字,并将其存储为id
。(?P<slug>[\w-]+)
捕获一个包含字母、数字、下划线和连字符的字符串并将其存储为slug
。
在 views.py
中定义如何处理这个视图:
# blog/views.py
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from .models import Post # 假设你有这个模型
def post_detail(request, id, slug):
# 使用 get_object_or_404 确保获取的文章存在
post = get_object_or_404(Post, id=id)
# 返回文章详情
return HttpResponse(f"你正在查看的文章是:{post.title},Slug: {slug}")
可以通过以下 URL 来访问文章详情:
/post/1/python-introduction/
/post/23/another-article/

获取 GET 请求参数(如 /search/?q=xxx
)
什么是 GET 请求参数?
当你访问一个 URL,并带上参数,如:
/search/?q=django
这叫 GET 请求参数,q=django
中:
q
是参数名django
是参数值
常用于搜索功能、筛选功能等。
单个键单个值 get 请求
代码讲解:
urls.py
path('search/', views.search, name='search')
views.py
from django.http import HttpResponse
def search(request):
query = request.GET.get('q') # 从 URL 中取出参数 q 的值
return HttpResponse(f"搜索关键词:{query}")
访问 /search/?q=django
会返回 “搜索关键词:django”
继续完善和扩展:如果你希望能返回标题或内容中包含 “django” 的所有文章(Post
)。
修改 views.py
中的 search
视图
# blog/views.py
from django.shortcuts import render
from .models import Post
def search(request):
query = request.GET.get('q') # 从 URL 中获取查询参数
if query:
# 使用 Django ORM 进行模糊查询
posts = Post.objects.filter(title__icontains=query) | Post.objects.filter(content__icontains=query)
else:
# 如果没有搜索关键词,返回空结果或所有文章
posts = Post.objects.none() # 返回一个空的 QuerySet
return render(request, 'blog/search_results.html', {'query': query, 'posts': posts})
这里的关键点是使用 icontains
来实现不区分大小写的模糊查询,返回标题或内容中包含指定关键词的所有文章。
添加一个模板 search_results.html
文件路径:templates/blog/search_results.html
<!DOCTYPE html>
<html>
<head>
<title>搜索结果</title>
</head>
<body>
<h1>搜索关键词:{{ query }}</h1>
{% if posts %}
<ul>
{% for post in posts %}
<li>
<strong>{{ post.title }}</strong><br>
<small>作者:{{ post.author.name }} | 时间:{{ post.created_at }}</small><br>
<p>{{ post.content }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>没有找到相关的文章。</p>
{% endif %}
</body>
</html>
页面会显示标题或内容中包含 “django” 的所有文章,如:

多个键值对
如果您需要处理多个查询参数,可以使用 request.GET
来提取多个参数的值。这是一个类字典对象,允许您访问 URL 中的所有查询参数。您可以通过参数名称来访问相应的参数值,并且可以提供默认值以处理参数可能不存在的情况。
以下是一个示例代码:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('search/', views.search, name='search')
]
# views.py
from django.http import HttpResponse
def search(request):
# 从 URL 中获取多个参数的值
keyword = request.GET.get('q', '') # 当参数不存在时,默认值为空字符串
category = request.GET.get('category', 'all') # 当参数不存在时,默认值为 'all'
date = request.GET.get('date', None) # 当参数不存在时,默认值为 None
response_text = f"搜索关键词:{keyword}, 类别:{category}, 日期:{date}"
return HttpResponse(response_text)
在这个例子中,我们查询三个参数:q
、category
和 date
。URL 访问示例:
/search/?q=django&category=books&date=2023-01-01
会返回 "搜索关键词:django, 类别:books, 日期:2023-01-01"/search/?q=django&category=books
会返回 "搜索关键词:django, 类别:books, 日期:None"/search/?category=books
会返回 "搜索关键词:, 类别:books, 日期:None"
单个键多个值 request.GET.getlist()
假设您正在处理一个允许用户选择多个类别进行搜索的场景,这里是一个使用 request.GET.getlist()
的例子
例如,您有一个搜索接口,用户可以通过多个类别进行搜索,使用 URL 参数的形式如下:/search/?category=books&category=music&category=movies
:
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('search/', views.search, name='search'),
]
# views.py
from django.http import HttpResponse
def search(request):
# 使用 getlist() 获取所有 category 参数的值列表
categories = request.GET.getlist('category')
# 将类别列表转换为一个字符串,以便在响应中显示
categories_str = ", ".join(categories)
response_text = f"选择的类别:{categories_str}"
return HttpResponse(response_text)
在这个例子中,request.GET.getlist('category')
将返回 ['books', 'music', 'movies']
。然后,我们将这些值合并成一个字符串并返回给客户端。

请求体body中发送数据(表单数据、json、xml)
获取 POST 表单参数
什么是 POST 表单提交?
POST 请求通常用于向服务器提交数据(比如用户发评论、注册、登录等)。
HTML 中写 <form method="post">
,就代表是 POST 请求。
路由配置:urls.py
这是 URL 路由系统的入口,你必须定义“表单页面”和“处理提交”的地址:
from django.urls import path
from . import views
urlpatterns = [
path('comment/', views.comment_page, name='comment_page'), # 用户访问这个页面填写评论
path('submit_comment/', views.comment_post, name='comment_post'), # 提交表单数据处理
]
前端页面:templates/blog/comment.html
必须创建一个 HTML 页面,里面包含 <form>
表单。
<!-- templates/blog/comment.html -->
<!DOCTYPE html>
<html>
<head>
<title>发表评论</title>
</head>
<body>
<h1>评论文章</h1>
<!-- 表单区域 -->
<form method="post" action="{% url 'comment_post' %}">
{% csrf_token %} <!-- 防止跨站攻击,必须有 -->
<textarea name="content" placeholder="写下你的评论..." rows="5" cols="40"></textarea>
<br>
<button type="submit">提交评论</button>
</form>
</body>
</html>
表单字段 | 含义 |
---|---|
method="post" | 表示使用 POST 请求提交数据 |
action="{% url 'comment_post' %}" | 提交数据到后端处理路径(匹配上面第二个路由) |
name="content" | 表示评论内容字段,后端要用这个名字提取值 |
{% csrf_token %} | Django 安全机制要求表单必须带上这个字段 |
后端视图函数处理表单提交:views.py
from django.http import HttpResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt # 如果你没用 {% csrf_token %},可临时关闭 CSRF
def comment_page(request):
return render(request, 'blog/comment.html')
@csrf_exempt # 如果你没有 {% csrf_token %},临时加这个。生产环境不要加
def comment_post(request):
if request.method == "POST":
content = request.POST.get("content")
return HttpResponse(f"你提交的评论内容是:{content}")
return HttpResponse("请通过 POST 提交")
完整流程演示:
步骤 | 说明 |
---|---|
用户访问 /comment/ | 会触发 views.comment_page ,渲染并显示 comment.html 表单页面 |
用户填写评论并点击“提交”按钮 | 浏览器向 /submit_comment/ 发出一个 POST 请求 |
后端的 comment_post() 处理函数会被调用 | 从 request.POST.get('content') 中获取表单字段值,进行处理或保存 |
难点:请问用户填写评论并点击“提交”按钮后,为什么会触发浏览器向 /submit_comment/ 发出一个 POST 请求?
用户填写评论并点击“提交”按钮后,浏览器会向 /submit_comment/
发送 POST 请求的原因是由于 HTML <form>
元素的配置。以下是 HTML <form>
的关键属性,以及它们如何影响数据提交:
method="post"
:- 这意味着表单数据将使用 HTTP POST 方法提交。POST 请求被用于向服务器发送数据以创建或更新资源。
action="{% url 'comment_post' %}"
:- 这个属性定义了表单数据提交的目标 URL。在这个例子中,
{% url 'comment_post' %}
是 Django 模板标签,它将被解析为 URL 路由系统中名称为'comment_post'
的路径。因此,这会生成/submit_comment/
路径(通过 name='comment_post' 方向解析出路径),依据您在urls.py
中定义的路由。 - 因此,当用户点击提交按钮时,请求会被发送到
/submit_comment/
。
- 这个属性定义了表单数据提交的目标 URL。在这个例子中,

整个步骤过程:
- 用户请求表单页面:
- 请求: 用户在浏览器中访问 URL
/comment/
。 - 处理: Django 路由将该请求对应到
views.comment_page
。 - 响应:
comment_page
函数通过render
将templates/blog/comment.html
页面返回给客户端。 - 展示: 浏览器渲染并显示 HTML 表单页面给用户。
- 请求: 用户在浏览器中访问 URL
- 用户填写表单并提交:
- 操作: 用户在浏览器中填写评论内容,并点击提交按钮。
- 网络请求: 浏览器根据
<form>
元素的method
和action
属性,向/submit_comment/
发出一个 POST 请求。
- 服务器处理提交的表单数据:
- 请求收集: POST 请求由 Django 框架处理,并通过 URL 路由系统对应到
views.comment_post
。 - 数据处理:
comment_post
函数检查请求方法为 POST,提取数据request.POST.get('content')
。 - 响应生成: 将提取的评论内容生成响应,并以
HttpResponse
返回给客户端。
- 请求收集: POST 请求由 Django 框架处理,并通过 URL 路由系统对应到
- 响应到客户端:
- 用户可见: 浏览器接收来自服务器的响应,并呈现给用户(例如显示“你提交的评论内容是:…”)。
可以用postman 测试过程
- 请求设置:
- 打开 Postman,选择 HTTP 请求类型为
POST
。 - 设置请求 URL 为
http://your-server-domain/submit_comment/
(替换your-server-domain
为实际服务器地址或localhost
)。
- 打开 Postman,选择 HTTP 请求类型为
- 设置请求 Body:
- 在
Body
标签中,选择x-www-form-urlencoded
。 - 添加一个键值对:
- Key:
content
- Value: 输入您想测试的评论内容,例如
This is a test comment
.
- Key:
- 在
- 发送请求:
- 点击
Send
发送请求。
- 点击
- 查看响应:

POST 方式传递和解析 json 数据
传递和解析 JSON 数据在现代 web 应用中非常普遍,尤其是在使用 JavaScript 和后端 API 通信时。以下是基础概念和一个简单的例子。
JSON 数据介绍
- JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人和机器读取和写入。
- 它基于键值对结构,类似于 Python 的字典或 JavaScript 的对象。
- JSON 数据类型包括字符串、数字、布尔值、数组和对象。
传递 JSON 数据
可以通过 HTTP POST 请求发送 JSON 格式的数据。通常这会在应用程序的前端和后端之间进行。
案例:传递和解析 JSON 数据
假设有一个 Django 后端应用,需要处理用户的个人信息,该信息以 JSON 格式传递。
修改 urls.py
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('user_info/', views.user_info, name='user_info'), # 配置路由以处理用户信息请求
]
后端视图处理 JSON 数据 (views.py)
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
@csrf_exempt # 再生产环境应启用 CSRF 防护机制,目前为了便于测试禁用
def user_info(request):
if request.method == "POST":
try:
# 从请求体中解析 JSON 数据
data = json.loads(request.body) # json 形式的字符串不太好操作,一般都会通过 json.loads转化成字符串
name = data.get('name')
age = data.get('age')
# 可以对数据进行处理或存储
return JsonResponse({'message': f'Hello, {name}, your age is {age}.'})
except json.JSONDecodeError:
return JsonResponse({'error': 'Invalid JSON'}, status=400)
return JsonResponse({'error': 'Only POST method allowed'}, status=405)
可以使用 Postman 或任何其他 HTTP 客户端工具进行测试:
- 请求设置:
- 打开 Postman,选择请求类型为
POST
。 - 设置请求 URL 为
http://your-server-domain/user_info/
。
- 打开 Postman,选择请求类型为
- 设置请求 Header:
- 确保
Content-Type
设置为application/json
。
- 确保
- 设置请求 Body:
- 在
Body
标签中,选择raw
。 - 输入 JSON 数据,例如:
- 在
{
"name": "John Doe",
"age": 30
}
- 发送请求:
- 点击
Send
发送请求。
- 点击
- 查看响应:
- 服务器应该返回一条消息,确认已成功接收到并处理了 JSON 数据。

json.dumps
和 json.load
json.dumps
用于将 Python 对象(如字典或列表)序列化为 JSON 格式的字符串。这个过程称为“序列化”。序列化的主要用途是在数据在网络传输或存储到文件时,将数据转换为一种标准格式。
用法示例:
import json
data = {
"name": "John Doe",
"age": 30,
"active": True,
"roles": ["admin", "user"]
}
# 将 Python 对象序列化为 JSON 字符串
json_string = json.dumps(data)
print(json_string)
在这个示例中,json.dumps(data)
将 Python 字典转换为 JSON 字符串,并将结果打印出来。
json.load
用于从文件对象中读取 JSON 数据,并将其解析为 Python 对象。这与 json.loads
有所不同,因为 json.loads
解析的是字符串,而 json.load
解析的是文件。
假设我们有一个文件 data.json
,其内容如下:
{
"name": "Jane Doe",
"age": 25,
"active": false,
"roles": ["editor", "user"]
}
我们用 json.load
读取这个文件:
import json
# 打开 JSON 文件进行读取
with open('data.json', 'r') as file:
# 使用 json.load 解析文件中的 JSON 数据
data = json.load(file)
print(data)
在这个示例中,json.load(file)
从文件中读取 JSON 数据并解析为 Python 字典,然后将结果打印出来。
请求头获取
在处理 HTTP 请求时,请求头(HTTP Headers)是非常重要的部分。请求头携带了关于客户端环境、请求细节、传输数据等多种信息,这些信息用于告知服务器如何处理请求。理解和使用请求头是开发 Web 应用时的基本技能之一。
- Content-Type:
- 描述请求体的媒体类型。例如,
application/json
表示请求体是 JSON 数据,application/x-www-form-urlencoded
表示表单数据。 - 服务器通过这个头来决定如何解析请求体内容。
- 描述请求体的媒体类型。例如,
- Accept:
- 指定客户端能够处理的内容类型。这意味着客户端期望从服务器接收的数据类型,比如
text/html
或application/json
。 - 服务器根据 Accept 头选择合适的 MIME 类型进行响应。
- 指定客户端能够处理的内容类型。这意味着客户端期望从服务器接收的数据类型,比如
- Authorization:
- 包含用于验证客户端身份的凭据信息。它常用于实施认证机制,如 Basic Auth、Bearer Token 等。
- 安全性关键,用于保护 API,确保只有授权用户才能访问。
- User-Agent:
- 提供有关发起请求的客户端的详细信息,通常是浏览器名称和版本。
- 服务器可以使用 User-Agent 头来定制响应内容,比如为不同浏览器优化显示。
- Accept-Language:
- 指定客户端能够理解的语言种类,例如
en-US
表示美国英语。 - 服务器可以基于这个信息提供多语言支持。
- 指定客户端能够理解的语言种类,例如
- Referer:
- 包含表示请求来源的 URL,指示用户从哪个页面链接到当前请求的资源。
- 较常用于分析流量源或防止 CSRF 攻击。
- Cookie:
- 包含与请求关联的 cookie 数据,通常包括会话信息。
- 服务器可以利用 cookie 头来跟踪会话状态。
- Cache-Control:
- 指示客户端的缓存机制相关指令,控制如何缓存请求和响应数据。
- 服务器可以根据 Cache-Control 头调整对客户端的缓存策略。
在 Django 或其他 Web 框架中,处理请求头非常方便。通常可以通过 request.headers
访问请求头。例如,在 Django 中:
def my_view(request):
content_type = request.headers.get('Content-Type', '')
user_agent = request.headers.get('User-Agent', '')
# Do something with the request headers
print(f'Content-Type: {content_type}')
print(f'User-Agent: {user_agent}')

常用的 httprequest 对象属性
常用的 HttpRequest
属性
GET
:- 包含查询字符串参数,是一个
QueryDict
对象。 - 使用示例:
request.GET['param_name']
- 包含查询字符串参数,是一个
POST
:- 包含请求主体中的表单数据,也是一个
QueryDict
。 - 使用示例:
request.POST['param_name']
- 包含请求主体中的表单数据,也是一个
FILES
:- 包含上传的文件信息,是一个
MultiValueDict
。 - 使用示例:
request.FILES['file_field_name']
- 包含上传的文件信息,是一个
COOKIES
:- 一个字典,包含请求中发送的所有 cookies。
- 使用示例:
request.COOKIES['cookie_name']
HTTP 响应返回
常用的响应类总结
类名 | 说明 | 用途示例 |
---|---|---|
HttpResponse | 返回纯文本或 HTML | 返回普通字符串、HTML、状态码 |
render | 返回渲染后的模板页面 | 常用于展示网页 |
redirect | 重定向到新地址 | 登录后跳转,提交表单后跳转等 |
JsonResponse | 返回 JSON 数据 | 前后端交互、AJAX 请求 |
HttpResponseNotFound | 返回 404 响应 | 页面不存在时使用 |
HttpResponseRedirect | 和 redirect() 类似,直接构造跳转响应 |
假设你的 app 叫做 blog
,我们现在要在 blog/views.py
和 blog/urls.py
中写代码。
一、HttpResponse():返回纯文本或 HTML
views.py
from django.http import HttpResponse
def hello(request):
return HttpResponse("你好,世界!")
def forbidden(request):
return HttpResponse("禁止访问", status=403)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello, name='hello'),
path('forbidden/', views.forbidden, name='forbidden'),
]
访问 /hello/
→ 显示文本「你好,世界!」
访问 /forbidden/
→ 显示文本「禁止访问」,状态码 403

二、render():返回 HTML 模板页面
views.py
from django.shortcuts import render
def index(request):
return render(request, 'blog/index.html', {"title": "博客首页"})
urls.py
path('index/', views.index, name='index'),
templates/blog/index.html
示例模板:
<!DOCTYPE html>
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}</h1>
<p>欢迎来到首页!</p>
</body>
</html>
访问 /index/
→ 渲染 HTML 模板页面

三、redirect():页面跳转
views.py
from django.shortcuts import redirect
def login_success(request):
return redirect('/hello/') # 直接跳转到另一个路径
def redirect_named(request):
return redirect('index') # 跳转到命名路由
urls.py
path('login_success/', views.login_success, name='login_success'),
path('redirect_named/', views.redirect_named, name='redirect_named'),
访问 /login_success/
→ 会跳转到 /hello/
访问 /redirect_named/
→ 会跳转到 /index/
四、JsonResponse():返回 JSON 数据
views.py
from django.http import JsonResponse
def api_data(request):
data = {"name": "Django", "type": "framework"}
return JsonResponse(data)
urls.py
path('api/data/', views.api_data, name='api_data'),
访问 /api/data/
→ 返回 JSON:

五、FileResponse:下载文件
你可以先在项目根目录下放一个 PDF 文件,比如:example.pdf
views.py
from django.http import FileResponse
import os
def download_file(request):
filepath = os.path.join(os.path.dirname(__file__), 'example.pdf')
return FileResponse(open(filepath, 'rb'), as_attachment=True, filename='example.pdf')
urls.py
path('download/', views.download_file, name='download_file'),
访问 /download/
→ 下载 example.pdf 文件

实际开发中如何选择响应方式?
场景 | 推荐用法 |
---|---|
返回一个 HTML 页面 | render() |
提交表单成功后跳转 | redirect() |
AJAX/FetchAPI 请求获取数据 | JsonResponse() |
非页面的错误提示 | HttpResponse("错误信息", status=403) |
错误页面处理方式
主动返回:
from django.http import HttpResponseNotFound
def my_view(request):
return HttpResponseNotFound("页面不存在")
使用 get_object_or_404:
from django.shortcuts import get_object_or_404
post = get_object_or_404(Post, id=3)
根据模型和条件尝试从数据库中获取一条数据,如果找不到,就自动返回 404 页面(而不是抛出异常)
get_object_or_404(模型类, **查询条件)
- 模型类:你要查询的模型(比如
Post
) - 查询条件:用字段名=值的形式,比如
id=3
- 如果能查到,就返回那条记录
- 如果查不到,就返回
Http404
错误,自动显示 “页面未找到”
这种方式的好处:如果使用post = Post.objects.get(id=3),如果 id=3
的文章存在,一切正常
,如果不存在,会抛出异常 Post.DoesNotExist
,程序就会崩溃。而使用post = get_object_or_404(Post, id=3),程序更健壮,不需要自己写 try-except,并且可以自动处理错误页(返回 404)
发布者:LJH,转发请注明出处:https://www.ljh.cool/43491.html