Django 之所以被称为"Web 开发中的教科书",很大原因在于它把经典的设计模式用得既准又深。下面按"模式 → Django 中对应组件 → 源码级例子 → 一句话总结"四个维度,把最常用的 10 个设计模式一次梳理完。看完你能在代码里直接指出"这段就是 xxx 模式"。
- MTV(Model--Template--View)------Django 的"MVC" 模式角色
Model ↔ 数据访问
Template ↔ 表现层
View ↔ 业务逻辑/路由分发
源码定位
django/db/models/base.py(Model)
django/template/response.py(TemplateResponse)
django/views/generic/base.py(View)
最小例子
urls.py
path('book/int:pk/', views.BookDetailView.as_view(), name='book_detail')
views.py
class BookDetailView(DetailView): model = Book # → Model template_name = 'book/detail.html' # → Template # 自定义业务逻辑 def get_context_data(self, **kwargs): ctx = super().get_context_data(**kwargs) ctx['reviews'] = self.object.reviews.select_related('user') return ctx 一句话:MVC 的 Django 方言,把"控制器"拆解成 URLConf + View。
- Front Controller(前端控制器)------WSGI 入口 + URLConf 整个请求先被 django/core/handlers/wsgi.py:WSGIHandler 截获,再交给 ROOT_URLCONF 去二次分发,典型 Front Controller。
源码片段
class WSGIHandler(base.BaseHandler): def call(self, environ, start_response): request = self.request_class(environ) response = self.get_response(request) # → 进入 URL 解析 ... 一句话:单点入口,集中路由。
- Model--View--ViewModel(MVVM)------Django Forms Mode l(数据库字段)与 View(HTML 表单)形态不同,Forms 层充当 ViewModel,负责数据校验/转换。
例子
class RegisterForm(forms.Form): username = forms.CharField(max_length=150, regex=r'^[\w.@+-]+$') password = forms.CharField(widget=forms.PasswordInput) # 两次密码一致性逻辑 def clean_password2(self): ... 一句话:Forms = 服务端 ViewModel,把"数据库表示"与"页面表示"解耦。
- Active Record------Model 即表,对象即行 每个模型类直接映射一张表,实例即一行,封装 CRUD。
源码
django/db/models/base.py:Model.save/delete
例子
book = Book(title='Clean Code', price=58) book.save() # INSERT book.price = 48 book.save(update_fields=['price']) # UPDATE 一句话:对象自带数据库行为,数据+操作二合一。
- Manager / QuerySet------Factory + Strategy objects = Manager 实例,返回 QuerySet;QuerySet 延迟执行,内部用策略模式拼装 SQL。
源码
django/db/models/query.py:QuerySet
django/db/models/manager.py:Manager
例子
qs = Book.objects.filter(price__lte=50).select_related('publisher') qs = qs.exclude(stock=0) # 链式策略 sql = qs.query.str() # 只看 SQL,不查库 一句话:Manager 是工厂,QuerySet 是策略链。
- Middleware------职责链(Chain of Responsibility) 请求/响应对象在到达视图前要经过一串中间件,每个中间件可短路或追加功能。
源码
django/utils/deprecation.py:MiddlewareMixin
settings.MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', ... ]
自定义例子
class SimpleCorsMiddleware: def init (self, get_response): self.get_response = get_response def call(self, request): response = self.get_response(request) response['Access-Control-Allow-Origin'] = '*' return response 一句话:链表式处理,可插拔。
- Signals------观察者模式(Observer) 模型保存、用户登录等事件发出"信号",多个接收者解耦响应。
源码
django/dispatch/dispatcher.py:Signal
例子
from django.db.models.signals import post_save from django.dispatch import receiver
@receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) 一句话:发布-订阅,降低模块间耦合。
- Template Method------通用视图骨架 django/views/generic/base.py:View.dispatch 定义执行骨架(get/post 分支),子类只覆写"变体"方法。
例子
class BookCreateView(CreateView): model = Book fields = 'all' success_url = reverse_lazy('book_list') # 只覆写"模板方法"允许的小钩子 def form_valid(self, form): form.instance.created_by = self.request.user return super().form_valid(form) 一句话:父类搭框架,子类填细节。
- Decorator------函数视图增强 django/contrib/auth/decorators.py:login_required
django/views/decorators/cache.py:cache_page
例子
@login_required @cache_page(60 * 15) def dashboard(request): ... 一句话:不动原函数,动态叠加功能。
- Dependency Injection------设置就是"容器" Django 不靠硬编码类,而是把依赖放进 settings:
- 数据库后端 → DATABASES['default']['ENGINE']
- 认证后端 → AUTHENTICATION_BACKENDS
- 缓存 → CACHES
运行时用 django/conf/init.py:LazySettings 动态导入,符合 DI 思想。
一句话:配置即注入,替换实现无需改业务代码。
速查表(收藏级)
MTV / MVC → 目录结构一眼看懂
Front Controller → WSGIHandler + urls.py
MVVM → Forms/Serializers
Active Record → Model.save()
Factory → Manager
Strategy → QuerySet 链式过滤
Chain → Middleware
Observer → Signals
Template Method → generic.View
Decorator → @login_required
DI → settings.py
打开任意 Django 项目,你都能把上表对照到具体文件;面试时把"模式 + 源码位置"脱口而出,就是加分项。