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注册模型后自动生成可交互的后台管理界面。
MTV 架构:请求从进来走到哪一步
Django 的架构叫 MTV,三个字母分别是 Model、Template、View。和传统 MVC 比,View 对应的是 Controller,Template 对应的是 View——名字换了一下,思路是一样的分层。
一个 HTTP 请求进来之后的完整路径是:先经过 URLconf 匹配路由 → 找到对应的 View 函数 → View 调用 Model 查数据库 → 拿到数据后传给 Template 渲染成 HTML → 返回给浏览器。这五步骤永远不变,区别只在于每一步写多少代码。
| 层 | 职责 | 对应文件 |
|---|---|---|
| Model | 定义数据结构,操作数据库 | models.py |
| Template | HTML 模板,插入动态数据 | templates/ |
| View | 业务逻辑,协调 Model 和 Template | views.py |
| URLconf | URL 路径到 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 验证逻辑。
Admin 后台:零代码搞定管理界面
Django Admin 是它最让新手惊艳的功能。只要在 admin.py 里注册模型,Django 就会自动生成一个功能完整的后台管理界面——可以增删改查数据、搜索、过滤、分页、导出 CSV,连权限管理都自带。
# blog/admin.py
from django.contrib import admin
from .models import Post
admin.site.register(Post)
运行 python manage.py createsuperuser 创建管理员账号,启动开发服务器访问 /admin/,就能看到 Post 的管理界面。这个后台足够支撑小型项目的运营需求,不用另外写一套管理系统。
需要定制展示列、过滤器、编辑表单时,继承 ModelAdmin 类做扩展即可:
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ("title", "created_at", "views")
list_filter = ("created_at",)
search_fields = ("title", "content")
三行代码就让后台列表显示标题、时间、浏览量,右侧加了时间过滤器,顶部有搜索框。这种效率在别的框架里基本要写一整天。
部署上线:Gunicorn 加 Nginx
开发服务器 runserver 只适合本地调试,性能差且不安全。生产环境的标准架构是:Nginx 做静态资源和反向代理,Gunicorn 跑 Django 应用服务器。
# 安装依赖
pip install gunicorn
# 收集静态文件(CSS/JS 交给 Nginx)
python manage.py collectstatic
# 启动 Gunicorn(4 个工作进程)
gunicorn mysite.wsgi:application --bind 127.0.0.1:8000 --workers 4
Nginx 配置做两件事:把 /static/ 开头的请求直接返回静态文件,把其他请求反向代理到 127.0.0.1:8000 的 Gunicorn。这样静态资源走 Nginx 的高效发送,动态请求走 Python 应用,各司其职。
- DEBUG 必须关掉:settings.py 里 DEBUG=False,否则线上报错会暴露代码细节。
- ALLOWED_HOSTS 配好:加上你的域名,拒绝其他 Host 头的请求。
- 数据库换 PostgreSQL:开发用 SQLite 方便,生产建议换 MySQL 或 PostgreSQL,Django 改一行配置就行。
- HTTPS 用 Certbot:Let's Encrypt 免费证书,Nginx 一行配置搞定。
Django 把 Web 开发的重复性工作都做完了,你应该把时间花在业务逻辑上,而不是搭脚手架。