一、模型字段类型详解

在 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 小整数类型

整数类型深度对比

TINYINTSMALLINT是两种常用的整数类型,选择合适的类型能优化存储效率

维度 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 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从入门到实战》专栏!关注不迷路~

Django模型开发:模型字段、元数据与继承全方位讲解的更多相关文章

  1. 信贷风控模型开发----模型流程&好坏样本定义

    第二章 模型开发流程&好坏样本定义 2.1模型开发流程 2.1.1 评分模型流程图 2.1.2流程图阐述 该小结提出了一些数据指标,如果不明白没有关系,往后的文章笔者会一个个地解释这些指标的含 ...

  2. Django ORM (一) 创建数据库和模型常用的字段类型参数及Field 重要参数介绍

    创建一个 Django 项目及应用 django-admin startproject orm cd orm python manage.py startapp app01 在 models.py 上 ...

  3. django中模型详解-字段类型与约束条件

    这片博文来详细说明django模型的使用,涉及到django模型的创建,字段介绍,以及django模型的crud操作,以及一对一等操作. 在使用模型之前,我们首先设置数据库选项,django的默认数据 ...

  4. SNF快速开发平台2019-权限管理模型-记录级-字段级权限实践

    1.1.1  字段级权限 字段级权限适用于对不同人的能否查看或录入不同表不同字段的权限控制. 是否启用字段级权限配置 不启用字段级权限后,[用户权限管理]程序[字段级权限]按钮会隐藏,导致无法给管理其 ...

  5. 如何让django模型中的字段和model名显示为中文

    如何让django模型中的字段和model名显示为中文:在模型中加入class Meta即可 class People(models.Model): name = models.CharField(n ...

  6. odoo 开发入门教程系列-模型和基本字段

    模型和基本字段 在上一章的末尾,我们创建一个odoo模块.然而,此时它仍然是一个空壳,不允许我们存储任何数据.在我们的房地产模块中,我们希望将与房地产相关的信息(名称(name).描述(descrip ...

  7. PHPCMS V9二次开发]自定义字段模型-文本组

    phpcms v9,我们在做类似于酒店房型等类型的时候,需要用到文本组字段模型,但phpcms并未提供该模型.如下图所示效果: 展示效果如下: 步骤/方法 打开phpcms\modules\conte ...

  8. [PHPCMS V9二次开发]自定义字段模型-添加字段类型

    步骤/方法 打开phpcms\modules\content\fields目录,复制文件夹downfiles,并改名为textgroups. 打开phpcms\modules\content\fiel ...

  9. python django -2 ORM模型

    ORM简介 MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库 ORM是“对象-关系-映射”的简称 ...

  10. Django框架3——模型

    Django数据库层解决的问题 在本例的视图中,使用了pymysql 类库来连接 MySQL 数据库,取回一些记录,将它们提供给模板以显示一个网页: from django.shortcuts imp ...

随机推荐

  1. Python 潮流周刊#102:微软裁员 Faster CPython 团队(摘要)

    本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章.教程.开源项目.软件工具.播客和视频.热门话题等内容.愿景:帮助所有读者精进 Python 技术,并增长职 ...

  2. CUDA原子操作

    这节主要涉及到一个多线程情况下存在的数据竞争问题 -- 多个线程同时访问共享数据时,由于没有正确的同步机制,导致数据出现不一致的情况. C/C++ 多线程中,可以通过互斥锁(mutex).原子操作(a ...

  3. [已解决] Compilation error ptxas fatal : Value ‘sm_30‘ is not defined for option ‘gpu-name‘

    在用cmake编译cuda程序时,总是报Compilation error ptxas fatal : Value 'sm_30' is not defined for option 'gpu-nam ...

  4. HSRP、GLBP、VRRP、NSRP 协议对比与配置指南

    HSRP.GLBP.VRRP.NSRP 协议对比与配置指南 一.协议对比表 特性 HSRP (Cisco) GLBP (Cisco) VRRP (标准协议) NSRP (Juniper) 协议类型 思 ...

  5. 分享95套Java实战项目,一次学个够

    第01项目:SSM大型互联网电商项目(视频+源码) 第02项目:SSM分布式互联网商城(视频+文档资料) 第03项目:SSM开发大中点平 (视频+源码) 第04项目:SSM分布式苗杀系统企业级实战(视 ...

  6. AI生成应用:图片批量重命名工具 - 自动化整理您的图片库

    图片批量重命名工具 - 自动化整理您的图片库 GitHub项目地址: https://github.com/dependon/renameImage 项目介绍 这是一个基于Python开发的图形界面工 ...

  7. Java 压缩成zip文件

    综述 在< 把多个文件打包压缩成tar.gz文件并解压的Java实现>中介绍了如何把文件压缩车gz文件,这里介绍如何把文件压缩成zip文件.支持如下方式的压缩: 压缩单个文件 压缩文件夹下 ...

  8. 如何实现本地大模型与MCP集成

    1.概述 本文将围绕构建兼具本地运行大型语言模型(LLM)与MCP 集成能力的 AI 驱动工具展开,为读者提供从原理到实践的全流程指南.通过深度整合本地大模型的隐私性.可控性优势与 MCP 工具的自动 ...

  9. 关于js中的toLocaleDateString()方法

    toLocaleDateString()方法是JavaScript Date对象的一个内建方法,它将日期转换为符合特定地区习惯的字符串格式. 基本用法: 如果没有传入任何参数,toLocaleDate ...

  10. java的5种异常的语法

    1 try{}catch(){} ​ 2 try{}catch(){}catch(){} ​ 3 try{}catch(){}finally{} ​ 4 try{}catch(){}catch(){} ...