Files
djangoadmin-wiki/DjangoAdmin_Django_AntdVue/zh/volume2/model.md
T
2026-09-12 23:12:15 +08:00

288 lines
7.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 数据模型(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 = 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}"
```
## 代码解析
### 基类继承
```python
class Example(BaseModel):
```
`BaseModel`(定义在 `application/models.py`)是一个抽象模型类,为所有业务模型提供以下 6 个公共字段:
| 字段 | 类型 | 说明 |
|:----|:----|:----|
| `id` | AutoField | 自增主键 |
| `create_user` | CharField(50) | 创建人 |
| `create_time` | DateTimeField | 创建时间(auto_now_add) |
| `update_user` | CharField(50) | 更新人 |
| `update_time` | DateTimeField | 更新时间(auto_now) |
| `is_delete` | BooleanField | 逻辑删除标识(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_name` | Django 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_name` | Django 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` 过滤已删除数据。