Become a sponsor

Model 层负责定义数据库表结构,所有业务模型继承 BaseModel 抽象基类,自动获得公共字段(id、create_user、create_time、update_user、update_time、is_delete)。
设计原则
BaseModeldb_comment 注释get_table_name() 生成表名application/models.py 定义了 BaseModel 抽象基类:
from django.db import models
class BaseModel(models.Model):
"""基础模型抽象类"""
# 主键ID字段
id = models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name='主键ID',
db_comment='主键ID'
)
# 创建人字段
create_user = models.CharField(
null=True, max_length=50, default=None,
verbose_name='创建人', db_comment='创建人'
)
# 创建时间字段
create_time = models.DateTimeField(
null=True, auto_now_add=True,
verbose_name="创建时间", db_comment='创建时间'
)
# 更新人字段
update_user = models.CharField(
null=True, max_length=50, default=None,
verbose_name='更新人', db_comment='更新人'
)
# 更新时间字段
update_time = models.DateTimeField(
null=True, auto_now=True,
verbose_name="更新时间", db_comment='更新时间'
)
# 逻辑删除标识
is_delete = models.BooleanField(
default=0, db_default=0,
verbose_name="逻辑删除",
db_comment='逻辑删除:0-正常 1-已删除'
)
class Meta:
abstract = True以案例模块为例,application/example/models.py:
from django.db import models
from application.models import BaseModel
from utils.common import get_table_name
class Example(BaseModel):
"""案例模型类"""
# 案例名称
name = models.CharField(
null=False, max_length=100, db_index=True,
verbose_name="案例名称",
help_text="案例名称",
db_comment='案例名称'
)
# 案例图片
avatar = models.CharField(
null=True, blank=True, max_length=255,
verbose_name="案例图片",
help_text="案例图片",
db_comment='案例图片'
)
# 案例类型
TYPE_CHOICES = (
(1, "类型1"),
(2, "类型2"),
(3, "类型3"),
(4, "类型4"),
)
type = models.IntegerField(
null=False, choices=TYPE_CHOICES,
verbose_name="案例类型:1-类型1 2-类型2 3-类型3 4-类型4",
help_text="案例类型:1-类型1 2-类型2 3-类型3 4-类型4",
db_comment='案例类型:1-类型1 2-类型2 3-类型3 4-类型4'
)
# 案例状态
STATUS_CHOICES = (
(1, "正常"),
(2, "禁用"),
)
status = models.IntegerField(
null=False, choices=STATUS_CHOICES,
verbose_name="案例状态:1-正常 2-禁用",
help_text="案例状态:1-正常 2-禁用",
db_comment='案例状态:1-正常 2-禁用'
)
# 排序
sort = models.IntegerField(
null=False,
verbose_name="排序",
help_text="排序",
db_comment='排序'
)
class Meta:
db_table = get_table_name('example')
db_table_comment = "案例表"
verbose_name = "案例表"
verbose_name_plural = verbose_name
ordering = ("sort",)
def __str__(self):
return f"案例{self.name}"| 数据库类型 | Django 字段类型 | 说明 |
|---|---|---|
| varchar | CharField | 短文本,需指定 max_length |
| text | TextField | 长文本 |
| int | IntegerField | 整数 |
| datetime | DateTimeField | 日期时间 |
| date | DateField | 日期 |
| float | FloatField | 浮点数 |
| decimal | DecimalField | 精确小数 |
| boolean | BooleanField | 布尔值 |
| 属性 | 说明 | 示例 |
|---|---|---|
null | 数据库是否允许 NULL | null=True |
blank | 表单验证是否允许空 | blank=True |
max_length | 最大长度 | max_length=100 |
default | 默认值 | default=0 |
db_index | 是否创建索引 | db_index=True |
choices | 选项列表 | choices=STATUS_CHOICES |
verbose_name | 字段中文名 | verbose_name="案例名称" |
help_text | 帮助文本 | help_text="案例名称" |
db_comment | 数据库字段注释 | db_comment='案例名称' |
# 状态字段
STATUS_CHOICES = (
(1, "正常"), # 正常状态
(2, "禁用"), # 禁用状态
)
status = models.IntegerField(
null=False, choices=STATUS_CHOICES,
verbose_name="状态:1-正常 2-禁用",
db_comment='状态:1-正常 2-禁用'
)选项定义约定
{FIELD}_CHOICES(value, label) 元组1-正常 2-禁用)class Meta:
# 数据表名(使用 get_table_name 自动生成)
db_table = get_table_name('example')
# 表注释(Django 4.1+)
db_table_comment = "案例表"
# Admin 后台显示名称
verbose_name = "案例表"
verbose_name_plural = verbose_name
# 默认排序
ordering = ("sort",)utils/common.py 中的 get_table_name 函数自动拼接表前缀:
from config.env import DATABASE_PREFIX
def get_table_name(table_name):
"""获取带前缀的表名"""
return f"{DATABASE_PREFIX}{table_name}"例如:DATABASE_PREFIX = "django_" 时,get_table_name('example') 返回 "django_example"。
class Example(BaseModel):
name = models.CharField(max_length=100, db_index=True) # 单列索引
class Meta:
indexes = [
models.Index(fields=['status', 'type'], name='idx_status_type'), # 复合索引
]项目使用 class_prepared 信号自动重排字段顺序,将公共字段(id、create_user 等)移到业务字段之后:
from django.db.models.signals import class_prepared
def _reorder_fields(sender, **kwargs):
"""重排模型字段顺序,将公共字段移到最后"""
# ... 实现逻辑 ...
class_prepared.connect(_reorder_fields)Model 层通过继承 BaseModel 获得公共字段,使用 get_table_name() 生成带前缀的表名。字段定义需包含 db_comment 注释、verbose_name 中文名。选项字段使用 choices 参数定义,排序使用 Meta.ordering 配置。