Skip to content

数据模型(Model)

数据模型是模块开发的第一步,用于定义数据库表结构。项目使用 Django ORM,模型类通过继承 BaseModel 自动获得通用字段。

文件位置

application/example/models.py

完整代码

python
from django.db import models

from application.models import BaseModel
from utils.common import get_table_name


# =============================================================
# 案例模型类
# =============================================================

class Example(BaseModel):
    """
    案例模型类

    用于存储系统中的案例信息。
    继承自 BaseModel,自动包含:
    - id: 主键
    - is_delete: 逻辑删除标识
    - create_user: 创建人
    - create_time: 创建时间
    - update_user: 更新人
    - update_time: 更新时间

    主要业务字段:
    - name: 案例名称
    - avatar: 案例图片
    - type: 案例类型
    - status: 案例状态(1-正常, 2-禁用)
    - sort: 排序权重(数值越小越靠前)
    """

    # ----------------------------------------------------------
    # 案例名称
    # ----------------------------------------------------------
    # 字段说明: 案例的名称
    # 字段类型: 字符串(CharField)
    # 约束: 非空(null=False),最大长度100字符
    # 索引: 添加了数据库索引(db_index=True)以提升查询效率
    # 作用: 案例的核心标识字段,用于列表展示和搜索
    name = models.CharField(
        null=False,
        max_length=100,
        db_index=True,
        verbose_name="案例名称",
        help_text="案例名称",
        db_comment='案例名称'  # 数据库字段注释
    )

    # ----------------------------------------------------------
    # 案例图片
    # ----------------------------------------------------------
    # 字段说明: 案例的图片
    # 字段类型: 字符串(CharField)
    # 约束: 允许为空(null=True, blank=True),最大长度255字符
    # 存储: 存储的是相对路径,通过 get_file_url() 生成完整访问URL
    # 作用: 用于案例列表展示和详情页的图片
    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"),
    )

    # 字段说明: 案例的分类类型
    # 字段类型: 整数(IntegerField)
    # 约束: 非空(null=False)
    # 选择项: 使用 TYPE_CHOICES 限制可选值
    # 作用: 对案例进行分类管理,支持按类型筛选
    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, "禁用"),  # 禁用状态:案例不对外展示
    )

    # 字段说明: 案例的显示状态
    # 字段类型: 整数(IntegerField)
    # 约束: 非空(null=False)
    # 选择项: 使用 STATUS_CHOICES 限制可选值
    # 作用: 控制案例是否在前端展示
    status = models.IntegerField(
        null=False,
        choices=STATUS_CHOICES,
        verbose_name="案例状态:1-正常 2-禁用",
        help_text="案例状态:1-正常 2-禁用",
        db_comment='案例状态:1-正常 2-禁用'  # 数据库字段注释
    )

    # ----------------------------------------------------------
    # 排序
    # ----------------------------------------------------------
    # 字段说明: 案例的排序权重
    # 字段类型: 整数(IntegerField)
    # 约束: 非空(null=False)
    # 排序规则: 数值越小越靠前(升序排列)
    # 作用: 手动控制案例在列表中的显示顺序
    sort = models.IntegerField(
        null=False,
        verbose_name="排序",
        help_text="排序",
        db_comment='排序'  # 数据库字段注释
    )

    # =============================================================
    # 模型元数据配置
    # =============================================================

    class Meta:
        """
        模型元数据配置类

        定义模型在数据库中的表名、显示名称、默认排序规则等。
        """

        # 数据表名
        # 使用配置文件中的表前缀 + "example",避免与其他应用表名冲突
        db_table = get_table_name('example')

        # 表注释(Django 3.2+ 支持)
        # 在数据库中生成 COMMENT 语句,便于数据库管理
        db_table_comment = "案例表"

        # 模型在admin后台显示的友好名称(单数)
        verbose_name = "案例表"

        # 模型在admin后台显示的友好名称(复数)
        verbose_name_plural = verbose_name

        # 默认排序规则
        # 按照 sort 字段升序排列(数值小的在前),确保显示顺序可控
        ordering = ("sort",)

    # =============================================================
    # 实例方法
    # =============================================================

    def __str__(self):
        """
        模型的字符串表示方法

        当需要将模型实例转换为字符串时调用,如admin后台显示、日志输出等。

        Returns:
            str: 包含案例名称的字符串
        """
        return f"案例{self.name}"

代码解析

基类继承

python
class Example(BaseModel):

BaseModel(定义在 application/models.py)是一个抽象模型类,为所有业务模型提供以下 6 个公共字段:

字段类型说明
idAutoField自增主键
create_userCharField(50)创建人
create_timeDateTimeField创建时间(auto_now_add)
update_userCharField(50)更新人
update_timeDateTimeField更新时间(auto_now)
is_deleteBooleanField逻辑删除标识(0=正常,1=已删除)

BaseModel 定义为 abstract = True,不会在数据库中创建对应的表。子类模型会继承这些字段,并在各自对应的表中创建这些列。

表名配置

python
db_table = get_table_name('example')

get_table_name() 函数(来自 utils/common.py)会自动拼接数据库表前缀:

python
def get_table_name(base_name):
    prefix = getattr(settings, 'DATABASE_PREFIX', '')
    return f"{prefix}{base_name}"

最终表名为 django_example(假设前缀为 django_)。所有业务表都使用此前缀,便于区分框架表与业务表。

字段定义

字符串字段

python
name = models.CharField(
    null=False,
    max_length=100,
    db_index=True,
    verbose_name="案例名称",
    help_text="案例名称",
    db_comment='案例名称'
)
参数说明
null=False数据库不允许为 NULL
max_length=100最大长度 100 字符
db_index=True创建索引,加速查询
verbose_nameDjango Admin 显示名称
help_text帮助文本
db_comment数据库字段注释

枚举字段

python
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'
)

choices 参数定义了字段的可选值,在 Django Admin 中会显示为下拉选择框。

可选字段

python
avatar = models.CharField(
    null=True,
    blank=True,
    max_length=255,
    verbose_name="案例图片",
    help_text="案例图片",
    db_comment='案例图片'
)
参数说明
null=True数据库允许为 NULL
blank=True表单验证允许为空

Meta 类配置

python
class Meta:
    db_table = get_table_name('example')  # 数据表名
    db_table_comment = "案例表"           # 表注释
    verbose_name = "案例表"               # Admin 显示名称(单数)
    verbose_name_plural = verbose_name    # Admin 显示名称(复数)
    ordering = ("sort",)                  # 默认排序
配置项说明
db_table数据库表名,使用 get_table_name() 自动加前缀
db_table_comment表注释,在数据库中生成 COMMENT 语句
verbose_nameDjango Admin 中显示的友好名称
ordering默认排序规则,按 sort 字段升序排列

枚举值约定

项目中状态字段统一使用整数枚举:

含义
1正常 / 启用
2禁用 / 停用

软删除字段 is_delete 由基类提供:0 = 正常,1 = 已删除。

BaseModel 源码参考

python
class BaseModel(models.Model):
    """基础模型抽象类"""

    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

开发要点

  1. 业务字段仅定义差异部分:通用字段(id、时间、软删除等)由基类 BaseModel 自动提供
  2. 表名必须使用 get_table_name() 加前缀:保持命名一致性
  3. 合理使用索引:查询频繁的字段(如 name、status)设置 db_index=True
  4. 每个字段都要设置 db_comment:便于数据库管理和维护
  5. 枚举字段使用 choices:在 Django Admin 中显示为下拉选择框
  6. 所有查询都要加 is_delete=False 条件:过滤已删除的数据

总结

数据模型继承 BaseModel(公共字段),表名使用 get_table_name() 自动加前缀。查询频繁的字段设置索引,每个字段都要设置 db_comment 数据库注释。所有查询都必须加 is_delete=False 过滤已删除数据。

小蚂蚁云团队 · 提供技术支持