Python · 2 分钟阅读
Admin 实现原理
Admin 看似神奇,本质是装饰器 + ContentType + ModelAdmin 的组合。
注册的本质
# 内部等价于
admin.site.register(Topic, TopicAdmin)
# 等价于
@admin.register(Topic)
class TopicAdmin(admin.ModelAdmin):
...
register 会把 Model 与 ModelAdmin 存入 AdminSite,再由 URLConf 自动生成对应路由。
两个核心 Python 概念
1. 装饰器
在不动原函数的前提下,给它"包一层":
import time, functools
def exec_time(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
print(f"{func.__name__} took {time.perf_counter() - start:.3f}s")
return result
return wrapper
@exec_time
def heavy():
...
带参数的装饰器 = “装饰器的装饰器”:
def exec_time(label):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
...
print(f"[{label}] ...")
return result
return wrapper
return decorator
@admin.register正是这类用法,它把 Model 也作为参数传入。
2. ContentType
django.contrib.contenttypes 记录"每个 App、每个 Model"的元信息,存于 django_content_type 表。
| 字段 | 含义 |
|---|---|
app_label |
应用名 |
model |
模型名(小写) |
ContentTypeManager 提供了:
get_for_model(Model)— 通过 Model 类取 ContentTypeget_for_id(pk)— 通过 id 取 ContentType(优先缓存)model_class()— 反向得到 Model 类
Admin 的工作流
register注册时记录 Model- 启动时通过 ContentType 验证 Model 存在
- URLConf 自动为每个 Model 生成增删改查路由
- ModelAdmin 决定列表页、详情页、搜索、过滤等行为
装饰器实用场景
- 日志 / 计时 / 限流
- 权限校验
- 事务包裹
- 缓存命中
Django 大量使用装饰器:
@login_required、@permission_required、@csrf_exempt、Admin 注册等。