Django 是什么:为什么选它而不是 Flask

Python Web 开发最常被拿来比较的两个框架是 Flask 和 Django。Flask 是微框架——轻量、灵活,你想用什么插件自己装;Django 是大框架——开箱即用,从数据库 ORM 到表单验证、从用户认证到 Admin 后台全部自带。选哪个取决于项目类型:快速做一个内容站、管理后台、内部工具,Django 的效率远超 Flask;需要极致灵活、微服务或 API 网关时,Flask 或 FastAPI 更合适。

Django 最出名的口号是"不要重复造轮子"。它把 Web 开发中最常见的需求都做了官方实现,而且做得足够好:ORM 不用手写 SQL、Auth 不用自己管密码哈希、CSRF 防护自动加、Admin 后台几行代码就生成。你写的代码几乎全是业务逻辑,不用花时间搭基础设施。

Django 适合"有明确数据模型、需要后台管理、快速上线"的项目;如果你只需要几个 JSON API,FastAPI 更轻。
本文核心知识点
  • MTVModel-Template-View,Django 的分层架构,对应 MVC 的变体。
  • ORM用 Python 类定义数据表,Django 自动生成 SQL。
  • 路由URLconf 把请求路径映射到视图函数。
  • Admin注册模型后自动生成可交互的后台管理界面。
Django Web 开发示意:蓝色渐变背景上网页面板悬浮于圆柱形数据库之上,由发光管线连接,背景山形剪影
Django 的世界:网页面板从数据库长出来,一条请求链路贯穿 Model、Template、View 三层。

MTV 架构:请求从进来走到哪一步

Django 的架构叫 MTV,三个字母分别是 Model、Template、View。和传统 MVC 比,View 对应的是 Controller,Template 对应的是 View——名字换了一下,思路是一样的分层。

一个 HTTP 请求进来之后的完整路径是:先经过 URLconf 匹配路由 → 找到对应的 View 函数 → View 调用 Model 查数据库 → 拿到数据后传给 Template 渲染成 HTML → 返回给浏览器。这五步骤永远不变,区别只在于每一步写多少代码。

层职责对应文件
Model定义数据结构,操作数据库models.py
TemplateHTML 模板,插入动态数据templates/
View业务逻辑,协调 Model 和 Templateviews.py
URLconfURL 路径到 View 的映射表urls.py

安装 Django 后用一条命令创建项目骨架:pip install django && django-admin startproject mysite。Django 会自动生成 settings.py(配置)、urls.py(路由入口)、wsgi.py(部署入口)。然后在项目里 python manage.py startapp blog 创建一个应用——一个 Django 项目可以包含多个 app,每个 app 是独立的业务模块。

ORM 建模:用 Python 类操作数据库

Django ORM 是它最强大的部分。你不需要写任何 SQL,只需要用 Python 类描述数据表结构,Django 会自动建表、做增删改查。

# blog/models.py
from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)
    views = models.IntegerField(default=0)

    def __str__(self):
        return self.title

这段代码定义了一张 Post 表:标题、正文、创建时间、浏览量。写完之后运行两条命令同步到数据库:

python manage.py makemigrations   # 生成迁移文件
python manage.py migrate           # 执行建表

之后在代码里操作数据就像操作 Python 对象一样:

# 查全部
posts = Post.objects.all()

# 条件查询
recent = Post.objects.filter(created_at__year=2026)

# 创建
Post.objects.create(title="你好", content="第一篇文章")

# 更新
post = Post.objects.get(id=1)
post.views += 1
post.save()

ORM 最直观的好处是查询可以链式组合,而且和 Python 的类型系统兼容,IDE 能自动补全。复杂查询用 filter 的双下划线语法(created_at__year、title__contains),连 JOIN 都不用手写。

视图与路由:写一个完整的列表页

视图是业务逻辑的入口。Django 的视图分两种:函数视图(FBV)和类视图(CBV)。简单页面用函数视图最直观:

# blog/views.py
from django.shortcuts import render
from .models import Post

def post_list(request):
    posts = Post.objects.all().order_by("-created_at")
    return render(request, "blog/post_list.html", {"posts": posts})

然后在 urls.py 里把路径映射到这个视图:

# blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("posts/", views.post_list, name="post_list"),
]

项目根 urls.py 再 include 这个 app 的路由:path("blog/", include("blog.urls"))。这样访问 /blog/posts/ 就会触发 post_list 视图,它查出所有文章,传给模板渲染。

类视图适合标准化的增删改查页面。Django 内置了 ListView、DetailView、CreateView 等通用视图,继承后只需要指定模型和模板名,几十行代码就能搭出完整的 CRUD 页面。

模板与表单:服务端渲染怎么做

Django 模板语言是一套小语法,用双花括号输出变量、用百分号写标签。它的设计原则是不让你在模板里写复杂业务逻辑——逻辑应该在视图里,模板只负责展示。

<!-- templates/blog/post_list.html -->
<h1>最新文章</h1>
{% for post in posts %}
  <article>
    <h2>{{ post.title }}</h2>
    <p>{{ post.created_at|date:"Y-m-d" }} · {{ post.views }} 次阅读</p>
    <p>{{ post.content|truncatechars:100 }}</p>
  </article>
{% empty %}
  <p>还没有文章。</p>
{% endfor %}

模板里的 {{ post.title }} 就是变量输出,{% for %} 是循环标签,|date 和 |truncatechars 是过滤器——类似管道,把变量加工一下再输出。Django 内置了几十种常用过滤器,格式化时间、截断文本、转义 HTML 都不用自己写。

表单处理是另一个高频场景。Django 提供了 Form 类,定义字段后自动生成 HTML、验证用户输入、返回错误信息。你不需要手写 <input> 标签,也不需要手写 if-else 验证逻辑。