文章目錄
- 一、模型字段類型詳解
- Django 與 MySQL 字段類型映射
- 整數類型深度對比
- 二、常用字段選項
- null 與 blank 的區別
- 注釋與幫助文本
- 默認值設置
- 日期時間特殊選項
- 選項列表(choices)
- 三、模型元數據與方法
- 模型 Meta 類
- 模型管理器(Manager)
- 自定義模型方法
- 四、模型繼承
- 抽象基類
- 模型繼承實戰
一、模型字段類型詳解
在 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 的區別
# 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
會觸發驗證錯誤
注釋與幫助文本
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
: 數據庫字段注釋
默認值設置
# 固定默認值
count = models.IntegerField(default=0)# 可調用對象作為默認值
from datetime import date
birth_date = models.DateField(default=date.today)
default
: 該字段的默認值
日期時間特殊選項
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 選項相互排斥,這些選項的任何組合都會導致報錯
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
定義字段的可選值范圍
# 直接定義選項
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
類定義模型的元數據,即 “非字段信息”
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
。 模型管理器只能通過模型類來訪問,一般用于“表級”操作
# 表級操作
all_users = User.objects.all()
active_users = User.objects.filter(is_active=True)
user = User.objects.get(id=1)
自定義模型方法
模型方法用于實現 “行級” 操作,可自定義業務邏輯
- 重寫 save() 方法:例如實現保存前后的處理
- 重寫 delete() 方法:例如實現軟刪除
- 其它自定義方法:例如編寫原生 SQL 語句
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()
)中調用
四、模型繼承
抽象基類
將公共字段提取到抽象基類,避免代碼重復
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
from django.db import modelsclass 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從入門到實戰》專欄!關注不迷路~