Django 从入门到精通:知行博客实战(6.1) · 第 5 / 36 节

URL、视图与请求响应

吴秀峰 4 次阅读 0 条评论 ↓

学习目标

为首页和关于页建立有名称的路由,使用反向解析和重定向,观察只读视图拒绝 POST 的行为。

为什么不要把地址写死在代码里

网站地址可能变化。如果每个模板、视图都写 /old-home/,改版时容易遗漏。给路由命名以后,可以用 blog:home 表达“博客首页”,让 Django 根据 URL 配置生成具体路径。app_name 则避免不同应用都叫 detail 时冲突。

视图接收 request,其属性包含请求方法、查询参数、用户等上下文。视图必须返回响应对象,不能直接返回普通字符串。redirect() 返回重定向响应,浏览器会再发起一次 GET;它不是把另一个页面直接拼进当前响应。

具体怎么做

  1. 替换 blog/views.py 和 blog/urls.py。
  2. 使用 @require_GET 说明三个页面只接受 GET,Django 会为其他方法返回 405。
  3. 保留 /old-home/ 演示重定向,便于理解以后保存表单后为什么回到详情页。
  4. 启动服务,依次打开 /、/about/、/old-home/ 和不存在的 /missing/。

本章新增或替换的完整文件

以下路径均相对于练习项目根目录。替换同名文件的全部内容;未列出的文件保持上一章版本。

blog/urls.py

from django.urls import path
from . import views
app_name = "blog"
urlpatterns = [
    path("", views.home, name="home"),
    path("about/", views.about, name="about"),
    path("old-home/", views.old_home, name="old_home"),
]

blog/views.py

from django.http import HttpResponse
from django.shortcuts import redirect
from django.views.decorators.http import require_GET

@require_GET
def home(request):
    return HttpResponse("知行博客:首页")

@require_GET
def about(request):
    return HttpResponse("这是一个用 Django 构建的学习型博客。")

@require_GET
def old_home(request):
    return redirect("blog:home")

如何确认成功

服务器启动后,在另一个终端执行;Windows 可使用 curl.exe 避免旧 PowerShell 的同名别名:

curl -i http://127.0.0.1:8000/about/
curl -i http://127.0.0.1:8000/old-home/
curl -i -X POST http://127.0.0.1:8000/about/

前两项分别为 200 和 302,重定向的 Location 是 /。带 CSRF 中间件时,未带 CSRF 的 POST 可能先返回 403;要单独验证视图方法限制,可使用下一条 Django 测试客户端命令(它默认关闭 CSRF 检查)。这说明请求会先经过中间件,不能只看视图代码预测所有响应。

python manage.py shell -c "from django.test import Client; print(Client(HTTP_HOST='localhost').post('/about/').status_code)"

预期输出 405。再验证反向解析:

python manage.py shell -c "from django.urls import reverse; print(reverse('blog:home')); print(reverse('blog:about'))"

练习:增加一个 /contact/ 只读页面,命名为 blog:contact,然后在 shell 中反向解析它。完成后可以保留练习,但本课程后续快照只包含主线文件。

常见问题

NoReverseMatch? 检查应用命名空间、路由名和需要的参数是否齐全。末尾斜杠为什么重要? 本教程 URL 统一带斜杠,表单 action 也用反向解析;不要依赖服务器为 POST 自动补斜杠。404 是服务器坏了吗? 不一定,它也用于表示当前用户看不到的对象,后面会用它保护草稿和他人文章。

官方参考

把学习连起来

登录后可保存阅读位置、标记章节完成,并在其他设备继续学习。

登录并保存学习进度 →
联系站长

微信:VIPdjango。技术问题建议先在 社区讨论 中交流,方便更多人参与和查阅。

章节讨论 0