第67课:Django 视图(Views)与 URL 路由
1. 学习目标
完成本课学习后,你将能够:
- 理解 Django 视图函数的基本作用与结构
- 编写并配置 URL 路由规则,将 Web 请求映射到对应的视图
- 使用路径转换器(Path Converters)处理动态 URL 参数
- 掌握反向解析(reverse)在模板和视图中的运用
- 区分函数视图(FBV)和基于类的视图(CBV)的基本用法
2. 核心概念
什么是视图(View)?
视图是 Django 中处理 HTTP 请求的核心逻辑。它接收一个 HttpRequest 对象,处理业务逻辑(如查询数据库),然后返回一个 HttpResponse 对象(通常是 HTML 页面、JSON 数据或重定向)。
简单来说,视图就是决定"用户看到什么"的地方。
什么是 URL 路由(URL Dispatcher)?
URL 路由就像一个智能快递分拣系统。当用户访问一个网址(如 /blog/1/),Django 的路由系统会根据你预先设定的规则,将这个请求"分拣"到对应的视图函数去处理。
路由规则通常写在 urls.py 文件中。
3. 代码示例
假设我们正在构建一个简单的博客应用,有文章列表和文章详情两个页面。
1. 定义视图函数(在 views.py 中)
# myapp/views.py
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404
# 模拟一些文章数据(实际项目会从数据库查询)
articles = [
{'id': 1, 'title': 'Django入门指南', 'content': 'Django是一个Python Web框架...'},
{'id': 2, 'title': '视图与URL详解', 'content': '今天来学习视图和URL...'},
]
def article_list(request):
"""处理文章列表请求的视图函数"""
# request 是 Django 自动传入的请求对象
# 这里简单返回一个字符串,实际项目中通常使用 render 渲染模板
return HttpResponse(f"欢迎来到博客!这里有 {len(articles)} 篇文章。")
def article_detail(request, article_id):
"""处理文章详情请求的视图函数,article_id 从URL中捕获"""
# 根据ID查找文章,如果找不到返回404
article = next((a for a in articles if a['id'] == article_id), None)
if article:
return HttpResponse(f"<h1>{article['title']}</h1><p>{article['content']}</p>")
else:
return HttpResponse("文章未找到", status=404)
def index(request):
"""首页视图"""
return HttpResponse("欢迎访问我的网站!<br><a href='/blog/'>查看博客</a>")
2. 配置 URL 路由(在 urls.py 中)
项目级 urls.py(通常位于 myproject/urls.py):
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls), # Django后台管理
path('blog/', include('myapp.urls')), # 将/blog/开头的URL交给myapp处理
path('', include('myapp.urls')), # 根路径也交给myapp(可选)
]
应用级 urls.py(创建在应用目录下 myapp/urls.py):
# myapp/urls.py
from django.urls import path
from . import views
# 应用命名空间,用于反向解析
app_name = 'blog'
urlpatterns = [
# 基础路径映射
path('', views.index, name='index'), # 根路径 -> index视图
# 文章列表
path('articles/', views.article_list, name='article-list'),
# 带参数的路径(使用<int:>转换器捕获数字ID)
path('articles/<int:article_id>/', views.article_detail, name='article-detail'),
# 更多转换器示例
path('archive/<int:year>/<int:month>/', views.archive, name='archive'),
path('author/<str:username>/', views.author_articles, name='author-articles'),
]
3. 在视图中使用反向解析
# 在视图函数中生成URL(避免硬编码)
from django.urls import reverse
def some_view(request):
# 生成名为 'blog:article-detail' 的URL,参数 article_id=1
url = reverse('blog:article-detail', kwargs={'article_id': 1})
# url 结果: '/blog/articles/1/'
return HttpResponse(f"<a href='{url}'>查看文章</a>")
4. 实践练习
练习1:基础URL配置
要求:为博客添加"关于"页面。
- 在
views.py中创建about视图,返回简单介绍文字 - 在
urls.py中添加路由规则:/blog/about/-> about视图 - 在
article_list视图中添加指向"关于"页面的链接
预期输出:访问 /blog/about/ 时显示"关于我们"页面,且从文章列表页可点击跳转。
练习2:带参数的视图
要求:实现按年归档功能。
- 创建
archive视图,接收year和month参数,返回类似"2024年1月的文章"的文字 - 配置URL:
/blog/archive/2024/1/→ archive视图 - 测试访问
/blog/archive/2024/1/和/blog/archive/2023/12/
预期输出:访问 /blog/archive/2024/1/ 时显示"2024年1月的文章"
练习3:整合数据库查询
要求:创建作者文章页面。
- 假设
Author模型有username字段(先创建简单模型) - 编写
author_articles视图:接收username参数,查询该作者的所有文章 - 配置URL:
/blog/author/张三/→ author_articles视图 - 返回文章列表或"该作者不存在"提示
5. 常见错误
-
忘记导入视图函数:
# 错误:忘记导入views from . import views # 正确做法 -
URL顺序问题:
urlpatterns = [ # 错误:通用路径在前,会被先匹配 path('<str:param>/', views.catch_all), path('specific/', views.specific_view), # 永远访问不到 ] # 正确:具体路径在前,通用路径在后 path('specific/', views.specific_view), path('<str:param>/', views.catch_all), -
路径转换器类型错误:
# 错误:期望数字但传入字符串 path('user/<int:user_id>/', views.profile) # 只会匹配数字 # 如果访问 /user/abc/ 会得到404错误 -
忘记在模板中使用反向解析:
<!-- 错误:硬编码URL,修改路径后需要全部修改 --> <a href="/blog/articles/1/">文章</a> <!-- 正确:使用反向解析 --> <a href="{% url 'blog:article-detail' article_id=1 %}">文章</a> -
视图函数没有返回 HttpResponse:
# 错误:忘记return def bad_view(request): print("Hello") # 正确:必须返回响应对象 def good_view(request): return HttpResponse("Hello")
6. 小结
本课我们学习了 Django Web 开发中两个核心组件:
视图(Views):
- 是处理请求、生成响应的核心逻辑
- 基本结构:接收
request,返回HttpResponse - 可以是函数(FBV)或类(CBV)
URL 路由:
- 通过
urls.py配置请求路径与视图的映射关系 - 使用
path()函数定义路由规则 - 支持路径转换器(
<int:>,<str:>,<slug:>等)捕获URL参数 - 推荐使用
app_name和name参数实现反向解析,避免硬编码
关键要点:
- 先编写视图函数,再配置URL路由
- 使用应用级
urls.py保持模块化 - 始终为URL模式命名,方便反向解析
- 动态参数通过路径转换器捕获并传递给视图
- 视图函数必须返回
HttpResponse对象
下一课我们将学习模板系统,了解如何将视图中的数据优雅地渲染成HTML页面呈现给用户。
练习编辑器
python
Loading...