1. Django 的设计哲学与 MTV 架构
Django 遵循 MVC (Model-View-Controller) 设计模式,但在 Django 中,它被称为 MTV (Model-Template-View)。虽然名称不同,但核心思想一致:关注点分离。
1.1 MTV 架构详解
在 Django 中,这三个核心组件的职责如下:
-
M (Model) - 数据存取层
- 职责:处理与数据库相关的所有事务。它负责定义数据的结构(相当于数据库表),并提供 API 来进行增、删、改、查(CRUD)操作。
- 对应文件 :通常位于应用目录下的
models.py。 - 作用:将业务逻辑与数据访问分离,无需编写 SQL 语句即可操作数据库。
-
T (Template) - 表现层
- 职责:决定页面如何展示给用户。它包含静态部分(HTML、CSS、JS)以及动态部分(模板语法,如变量、标签、过滤器)。
- 对应文件 :通常位于应用目录下的
templates/文件夹中。 - 作用:将业务逻辑与页面展示分离,使得设计师可以修改页面而不影响后端代码。
-
V (View) - 业务逻辑层
- 职责:处理 Web 请求。View 接收用户发来的 HttpRequest,通过 Model 获取数据,再加载 Template 进行渲染,最后返回 HttpResponse 给用户。
- 对应文件 :通常位于应用目录下的
views.py。 - 作用:它是 Model 和 Template 之间的桥梁,也是处理用户业务逻辑的地方。
1.2 工作流程图解
为了更直观地理解,我们可以看下用户访问一个 Django 页面时的数据流向:
- 用户在浏览器输入 URL 发起请求。
- URL Dispatcher (urls.py) :Django 的路由系统根据 URL 规则,将请求分发给对应的 View 函数。
- View (views.py) :
- 访问 Model 从数据库获取需要的数据。
- 加载 Template 模板文件。
- 将获取到的数据传递给模板进行渲染(填充动态内容)。
- Template (templates/):生成最终的 HTML 页面字符串。
- View 将渲染好的 HTML 封装在 HttpResponse 对象中返回给浏览器。
2. 核心组件实战:构建一个简单的"公告栏"功能
为了演示上述概念,我们将创建一个简单的功能:展示一条公告内容。
假设项目名为 mysite,应用名为 notice。
2.1 模型
模型是数据的唯一且权威的信息源。它包含您存储的数据的基本字段和行为。
文件位置 :notice/models.py
python
from django.db import models
class Notice(models.Model):
"""
公告模型
继承自 models.Model,这是 Django ORM 的基类
"""
# CharField 对应数据库中的 varchar 字段,max_length 是必填参数
title = models.CharField(max_length=200, verbose_name="标题")
# TextField 对应数据库中的 text 字段,用于长文本
content = models.TextField(verbose_name="内容")
# DateTimeField 用于存储日期和时间
pub_date = models.DateTimeField(auto_now_add=True, verbose_name="发布时间")
def __str__(self):
"""
定义对象的字符串表示
当在 Django Admin 或 Python Shell 中打印对象时,会显示此内容
"""
return self.title
class Meta:
# 定义该模型在后台显示的名称(单数/复数)
verbose_name = "公告"
verbose_name_plural = "公告"
教学点说明:
- 每个
class都对应数据库中的一张表。 - 每个
属性都对应表中的一个字段。 - 定义好模型后,需要运行迁移命令将 Python 代码转换为数据库表结构。
2.2 视图
视图是 Python 函数(或类),它接收 Web 请求并返回 Web 响应。
文件位置 :notice/views.py
python
from django.http import HttpResponse
from .models import Notice
def index(request):
"""
首页视图函数
参数 request:Django 自动传入的 HttpRequest 对象,包含请求的所有信息
"""
# 1. 数据获取:从数据库获取第一条公告
# 这里使用 ORM (Object-Relational Mapping) 语法,等同于 SQL: SELECT * FROM notice_notice LIMIT 1
latest_notice = Notice.objects.first()
# 2. 业务逻辑与渲染准备
# 这里为了演示简单,直接使用 Python 字符串格式化
# 在实际项目中,我们通常使用 Django Template 来处理 HTML
html = f"""
<html>
<head><title>公告栏</title></head>
<body>
<h1>{latest_notice.title if latest_notice else '暂无公告'}</h1>
<p>{latest_notice.content if latest_notice else ''}</p>
</body>
</html>
"""
# 3. 返回响应:将生成的 HTML 字符串封装在 HttpResponse 中返回
return HttpResponse(html)
教学点说明:
- 视图函数必须接收至少一个参数
request。 - 视图函数必须返回一个
HttpResponse对象。
2.3 模板
虽然上面的视图示例中使用了 Python 字符串拼接 HTML,但在实际开发中,我们使用 Template 来分离代码和页面结构。
文件位置 :notice/templates/notice/index.html (建议在 templates 下再建一个与应用同名的文件夹以避免冲突)
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>公告栏</title>
</head>
<body>
<!-- 使用 Django 模板变量语法:双大括号 {{ variable }} -->
<h1>{{ notice.title }}</h1>
<!-- 发布时间格式化过滤器:date:'Y-m-d H:i' -->
<p class="meta">发布于:{{ notice.pub_date|date:"Y-m-d H:i" }}</p>
<div class="content">
{{ notice.content }}
</div>
</body>
</html>
配合模板的改进版视图:
python
from django.shortcuts import render # 引入 render 快捷函数
from .models import Notice
def index(request):
latest_notice = Notice.objects.first()
# context 是一个字典,包含模板中需要用到的数据
context = {
'notice': latest_notice
}
# render 函数会自动加载模板,并将 context 填充进去,最后返回 HttpResponse
return render(request, 'notice/index.html', context)
教学点说明:
{``{ variable }}:用于输出变量。{``{ variable|filter }}:过滤器用于改变变量的显示格式(如日期格式化、截断字符串等)。render是 Django 提供的快捷函数,极大地简化了加载模板和构造响应的过程。
2.4 配置 URL (路由)
虽然 URL 配置不属于 MTV 中的任何一个字母,但它是连接用户请求与 View 的桥梁,是必不可少的。
文件位置 :notice/urls.py (需手动创建)
python
from django.urls import path
from . import views
urlpatterns = [
# 当用户访问根路径时,调用 views.index 函数
path('', views.index, name='notice_index'),
]
并在项目主路由 mysite/urls.py 中包含该应用的路由:
python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
# 将 notice 应用的所有路由包含到 /notice/ 路径下
path('notice/', include('notice.urls')),
]
3. 总结
本节我们学习了 Django 的 MTV 架构:
- Model (
models.py):负责定义数据结构,与数据库交互。 - View (
views.py):负责处理业务逻辑,获取数据并选择模板进行渲染。 - Template (
templates/):负责页面展示,包含 HTML 和 Django 模板语法。
通过这三层的分离,Django 使得代码结构清晰,易于维护和扩展。下一节,我们将深入探讨 Django ORM,学习如何更高效地进行数据库操作。
深入解析MTV
#todo