67·模块十三:Web开发基础进阶

Django 视图(Views)与 URL 路由

djangoviewsurls

第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配置

要求:为博客添加"关于"页面。

  1. views.py 中创建 about 视图,返回简单介绍文字
  2. urls.py 中添加路由规则:/blog/about/ -> about视图
  3. article_list 视图中添加指向"关于"页面的链接

预期输出:访问 /blog/about/ 时显示"关于我们"页面,且从文章列表页可点击跳转。

练习2:带参数的视图

要求:实现按年归档功能。

  1. 创建 archive 视图,接收 yearmonth 参数,返回类似"2024年1月的文章"的文字
  2. 配置URL:/blog/archive/2024/1/ → archive视图
  3. 测试访问 /blog/archive/2024/1//blog/archive/2023/12/

预期输出:访问 /blog/archive/2024/1/ 时显示"2024年1月的文章"

练习3:整合数据库查询

要求:创建作者文章页面。

  1. 假设 Author 模型有 username 字段(先创建简单模型)
  2. 编写 author_articles 视图:接收 username 参数,查询该作者的所有文章
  3. 配置URL:/blog/author/张三/ → author_articles视图
  4. 返回文章列表或"该作者不存在"提示

5. 常见错误

  1. 忘记导入视图函数

    # 错误:忘记导入views
    from . import views  # 正确做法
    
  2. URL顺序问题

    urlpatterns = [
        # 错误:通用路径在前,会被先匹配
        path('<str:param>/', views.catch_all),
        path('specific/', views.specific_view),  # 永远访问不到
    ]
    # 正确:具体路径在前,通用路径在后
    path('specific/', views.specific_view),
    path('<str:param>/', views.catch_all),
    
  3. 路径转换器类型错误

    # 错误:期望数字但传入字符串
    path('user/<int:user_id>/', views.profile)  # 只会匹配数字
    # 如果访问 /user/abc/ 会得到404错误
    
  4. 忘记在模板中使用反向解析

    <!-- 错误:硬编码URL,修改路径后需要全部修改 -->
    <a href="/blog/articles/1/">文章</a>
    
    <!-- 正确:使用反向解析 -->
    <a href="{% url 'blog:article-detail' article_id=1 %}">文章</a>
    
  5. 视图函数没有返回 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_namename 参数实现反向解析,避免硬编码

关键要点

  1. 先编写视图函数,再配置URL路由
  2. 使用应用级 urls.py 保持模块化
  3. 始终为URL模式命名,方便反向解析
  4. 动态参数通过路径转换器捕获并传递给视图
  5. 视图函数必须返回 HttpResponse 对象

下一课我们将学习模板系统,了解如何将视图中的数据优雅地渲染成HTML页面呈现给用户。

练习编辑器

python
Loading...

继续学习

完成本课后,建议继续学习下一课「Django 模板系统」 以巩固所学知识。