浅谈django的设计模式

Django 之所以被称为"Web 开发中的教科书",很大原因在于它把经典的设计模式用得既准又深。下面按"模式 → Django 中对应组件 → 源码级例子 → 一句话总结"四个维度,把最常用的 10 个设计模式一次梳理完。看完你能在代码里直接指出"这段就是 xxx 模式"。


  1. 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。


  1. 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 解析 ... 一句话:单点入口,集中路由。


  1. 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,把"数据库表示"与"页面表示"解耦。


  1. 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 一句话:对象自带数据库行为,数据+操作二合一。


  1. 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 是策略链。


  1. 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 一句话:链表式处理,可插拔。


  1. 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) 一句话:发布-订阅,降低模块间耦合。


  1. 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) 一句话:父类搭框架,子类填细节。


  1. Decorator------函数视图增强 django/contrib/auth/decorators.py:login_required
    django/views/decorators/cache.py:cache_page

例子

@login_required @cache_page(60 * 15) def dashboard(request): ... 一句话:不动原函数,动态叠加功能。


  1. 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 项目,你都能把上表对照到具体文件;面试时把"模式 + 源码位置"脱口而出,就是加分项。

相关推荐
哈里谢顿8 小时前
django操作mysql常见错误大全
mysql·django
梦弦189 小时前
Django:Python高效Web开发利器
python·django
luoluoal10 小时前
基于python的爬虫的贵州菜价可视化系统(源码+文档)
python·mysql·django·毕业设计·源码
luoluoal11 小时前
基于python的图像的信息隐藏技术研究(源码+文档)
python·mysql·django·毕业设计·源码
kobe_OKOK_17 小时前
Django缓存接口数据
python·缓存·django
张登杰踩18 小时前
django后台管理配置教程
后端·python·django
Warren9818 小时前
MySQL 8 中的保留关键字陷阱:当表名“lead”引发 SQL 语法错误
linux·数据库·python·sql·mysql·django·virtualenv
牢七19 小时前
Ucubug
django
kobe_OKOK_2 天前
windows 部署 django 的 方案
后端·python·django