一、模型字段类型详解
在 Django 开发中,模型(Model)是连接应用程序与数据库的核心桥梁。
Django 与 MySQL 字段类型映射
Django 模型的每个字段都是特定 Field 类的实例,它决定了数据库存储类型和表单验证规则。
Django 字段类型 | MySQL 数据类型 | 说明 |
---|---|---|
CharField |
VARCHAR |
字符串类型,需指定 max_length |
TextField |
TEXT |
长文本类型 |
IntegerField |
INT |
整数类型 |
BigIntegerField |
BIGINT |
长整数类型 |
BooleanField |
TINYINT(1) |
布尔类型(0=False,1=True) |
DateTimeField |
DATETIME |
日期时间类型 |
SmallIntegerField |
SMALLINT |
小整数类型 |
整数类型深度对比
TINYINT
和SMALLINT
是两种常用的整数类型,选择合适的类型能优化存储效率
维度 | TINYINT | SMALLINT |
---|---|---|
存储空间 | 1 字节(8 位) | 2 字节(16 位) |
有符号范围 | -128 到 127 | -32768 到 32767 |
无符号范围 | 0 到 255 | 0 到 65535 |
适用场景 | 布尔值、状态标记、年龄、枚举值等小范围数值 | 用户积分、订单数量等中等范围数值 |
示例 | 年龄(0-120)、月份(1-12)、星期(1-7) | 用户积分(0-5000)、订单数量(0-30000) |
二、常用字段选项
字段选项用于配置字段的行为特性,以下是开发中最常用的选项
null 与 blank 的区别
python
# null影响数据库存储,blank影响表单验证
field1 = models.CharField(max_length=100, null=True) # 数据库可存NULL
field2 = models.CharField(max_length=100, blank=True) # 表单可提交空值
field3 = models.CharField(max_length=100, null=True, blank=True) # 两者皆可
null=True
:允许数据库存储 NULL 值(默认 False)blank=True
:允许表单提交空值(默认 False)- 注意:前端提交
""
空字符串时,若blank=False
会触发验证错误
注释与帮助文本
python
class Book(models.Model):
title = models.CharField(
max_length=100,
help_text='Enter the book title', # 表单帮助文本
db_comment="图书标题" # 数据库字段注释(Django4.2+)
)
class Meta:
db_table_comment = 'This table stores information about books.' # 数据库表注释
help_text
:表单帮助文本db_comment
: 数据库字段注释
默认值设置
python
# 固定默认值
count = models.IntegerField(default=0)
# 可调用对象作为默认值
from datetime import date
birth_date = models.DateField(default=date.today)
default
: 该字段的默认值
日期时间特殊选项
python
class BaseModel(models.Model):
# 首次创建时自动设置当前时间
created_at = models.DateTimeField(auto_now_add=True)
# 每次save()时自动更新为当前时间
updated_at = models.DateTimeField(auto_now=True)
注意:
- auto_now在QuerySet.update()时不会自动生效,需手动更新或使用save()
- auto_now_add、auto_now 和 default 选项相互排斥,这些选项的任何组合都会导致报错
python
class Article(models.Model):
def save(self, *args, **kwargs):
if not self.pk: # 仅在首次创建时设置
self.created_at = timezone.now()
self.updated_at = timezone.now()
super().save(*args, **kwargs)
- 当需要复杂时间逻辑时,覆盖模型的 save() 方法
选项列表(choices)
使用choices
定义字段的可选值范围
python
# 直接定义选项
class Person(models.Model):
SHIRT_SIZES = [
("S", "Small"),
("M", "Medium"),
("L", "Large"),
]
shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
# 枚举类定义选项(推荐)
from enum import Enum
class UserTypeEnum(Enum):
MEMBER = 1 # 会员
ADMIN = 2 # 管理员
class User(models.Model):
user_type = models.SmallIntegerField(
choices=[(item.value, item.name) for item in UserTypeEnum],
default=UserTypeEnum.MEMBER.value
)
三、模型元数据与方法
模型 Meta 类
通过内部Meta
类定义模型的元数据,即 "非字段信息"
python
class User(models.Model):
username = models.CharField(max_length=50)
email = models.EmailField()
class Meta:
db_table = "system_users" # 数据库表名
db_table_comment = "用户信息表" # 数据库表注释
ordering = ['-id'] # 默认排序
verbose_name = "用户" # 单数显示名
verbose_name_plural = "用户" # 复数显示名
managed=False
适用于:
- 与遗留数据库集成时
- 不希望 Django 自动修改表结构的场景
模型管理器(Manager)
Manager 是模型与数据库交互的接口,默认名为objects
。 模型管理器只能通过模型类来访问,一般用于"表级"操作
python
# 表级操作
all_users = User.objects.all()
active_users = User.objects.filter(is_active=True)
user = User.objects.get(id=1)
自定义模型方法
模型方法用于实现 "行级" 操作,可自定义业务逻辑
- 重写 save() 方法:例如实现保存前后的处理
- 重写 delete() 方法:例如实现软删除
- 其它自定义方法:例如编写原生 SQL 语句
python
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, *args, **kwargs):
# 保存前处理
self.name = self.name.title()
super().save(*args, **kwargs) # 调用父类方法
# 保存后操作
self.clear_cache()
def clear_cache(self):
"""自定义缓存清理方法"""
cache.delete(f"blog_{self.id}")
注意:重写的模型方法不会在批量操作(例如update()
)中调用
四、模型继承
抽象基类
将公共字段提取到抽象基类,避免代码重复
python
class CommonInfo(models.Model):
"""抽象基类:包含公共字段"""
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True # 标记为抽象类,不生成数据表
# 继承抽象基类
class Student(CommonInfo):
home_group = models.CharField(max_length=5)
# 自动拥有name, age, created_at字段
class Teacher(CommonInfo):
department = models.CharField(max_length=50)
# 自动拥有name, age, created_at字段
模型继承实战
实战场景:在一个Django+Vue 后台管理系统中,需要维护多个数据表。这些数据表中,一般需要记录创建者、创建时间、更新者和更新时间等信息。可将该部分公共字段提取到抽象基类,避免代码重复。
定义抽象基类BaseModel
python
from django.db import models
class BaseModel(models.Model):
creator = models.CharField(
max_length=64, blank=True, null=True, default="", db_comment="创建者"
)
create_time = models.DateTimeField(auto_now_add=True, db_comment="创建时间")
updater = models.CharField(
max_length=64, blank=True, null=True, default="", db_comment="更新者"
)
update_time = models.DateTimeField(auto_now=True, db_comment="更新时间")
class Meta:
abstract = True
继承抽象基类:点击查看完整代码
实现效果
您正在阅读的是《Django从入门到实战》专栏!关注不迷路~