Django 快速入门:MTV模式与项目结构
Django 是 Python 语言中最流行的 Web 框架之一,以「含电池」(Batteries Included)著称,内置 ORM、表单处理、用户认证、管理后台等功能。本文将带你了解 Django 的 MTV 模式,并通过实战创建一个可运行的项目。
MTV 模式详解
Django 采用 MTV(Model-Template-View)架构,与传统 MVC 的对应关系如下:
- Model(模型):负责与数据库交互,定义数据结构,对应 Django 的 models.py
- Template(模板):负责渲染 HTML 页面,呈现数据给用户
- View(视图):负责业务逻辑,处理请求并返回响应,是 Model 和 Template 的桥梁
创建 Django 项目
首先安装 Django:
pip install django
django-admin startproject myproject
cd myproject
python manage.py startapp blog项目目录结构
myproject/
├── manage.py # Django CLI 管理工具
├── myproject/
│ ├── __init__.py
│ ├── settings.py # 项目配置文件
│ ├── urls.py # URL 路由配置
│ ├── wsgi.py # WSGI 入口
│ └── asgi.py # ASGI 入口
└── blog/
├── __init__.py
├── models.py # 模型定义
├── views.py # 视图函数
├── urls.py # 应用级 URL
├── admin.py # 管理后台
└── apps.py # 应用配置settings.py 关键配置
# myproject/settings.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "dev-key-replace-in-prod")
DEBUG = True # 生产环境设为 False
ALLOWED_HOSTS = ["example.com"]
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"blog",
]
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
LANGUAGE_CODE = "zh-hans"
TIME_ZONE = "Asia/Shanghai"
USE_TZ = True
STATIC_URL = "/static/"
MEDIA_URL = "/media/"
MEDIA_ROOT = BASE_DIR / "media"
ROOT_URLCONF = "myproject.urls"
定义第一个 Model
# blog/models.py
from django.db import models
from django.urls import reverse
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(unique=True)
class Meta:
verbose_name = "分类"
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
content = models.TextField()
category = models.ForeignKey(Category, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
is_published = models.BooleanField(default=False)
class Meta:
ordering = ["-created_at"]
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("article_detail", kwargs={"slug": self.slug})
编写第一个 View
# blog/views.py
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponse
from .models import Article
def article_list(request):
articles = Article.objects.filter(is_published=True)
return render(request, "blog/article_list.html", {"articles": articles})
def article_detail(request, slug):
article = get_object_or_404(Article, slug=slug, is_published=True)
return render(request, "blog/article_detail.html", {"article": article})
配置 URL 路由
# blog/urls.py
from django.urls import path
from . import views
app_name = "blog"
urlpatterns = [
path("", views.article_list, name="article_list"),
path("article//", views.article_detail, name="article_detail"),
]
myproject/urls.py(总路由)
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path("blog/", include("blog.urls")),
]
运行开发服务器
# 创建数据库表
python manage.py makemigrations
python manage.py migrate
创建管理员账号
python manage.py createsuperuser
启动服务器
python manage.py runserver
访问 http://127.0.0.1:8000/admin/ 管理后台
访问 http://127.0.0.1:8000/blog/ 查看文章列表</code></pre><h2>常见问题</h2><ul><li><strong>Q: 如何在视图中获取 URL 参数?</strong><br>A:Django 的 URL 捕获会自动传递给视图函数参数,例如 path("article/<int:id>/", views.detail) 会将 id 传递给 detail(request, id=123)。</li><li><strong>Q: DEBUG 模式和生产环境有什么区别?</strong><br>A:DEBUG=True 时会显示详细错误页面和加载静态文件;生产环境必须设为 False 并配置 ALLOWED_HOSTS、使用正式数据库。</li><li><strong>Q: 如何让 Django 支持中文?</strong><br>A:在 settings.py 中设置 LANGUAGE_CODE = "zh-hans" 和 TIME_ZONE = "Asia/Shanghai",确保 USE_I18N = True(默认)。</li><li><strong>Q: makemigrations 和 migrate 的区别是什么?</strong><br>A:makemigrations 根据模型变更生成迁移脚本文件;migrate 执行这些脚本应用到数据库。</li></ul><h2>延伸阅读</h2><ul><li><a href="https://docs.djangoproject.com/zh-hans/5.0/">Django 官方文档(中文)</a></li><li><a href="https://docs.djangoproject.com/en/5.0/ref/settings/">Django settings.py 完整配置参考</a></li><li>Django vs Flask vs FastAPI:如何选择 Python Web 框架</li></ul>