django入门【05】模型介绍(二)——字段选项

文章目录

    • 1、null 和 blank
      • 示例
      • 说明
      • ⭐ `null` 和 `blank` 结合使用的几种情况总结:
    • 2、choices
      • **`choices` 在 Django 中有以下几种形式:**
        • (1) **简单的列表或元组形式**
        • (2) **字典映射形式**
        • (3) **分组形式**
        • (4) **可调用对象**
        • (5)**枚举类型**
        • (6) **自定义数据类型的枚举**
    • 3. 基本 数据库 相关选项 (db_column、db_comment、db_default、db_index、db_tablespace)
    • 4. 默认值与编辑选项(default、editable)
    • 5. 错误消息与帮助文本(error_messages、help_text)
    • 6. 唯一性选项(primary_key、unique、unique_for_date、unique_for_month、unique_for_year)
    • 7. 其他选项(verbose_name、validators、自定义验证器)

1、null 和 blank

示例

class NullOrBlank(models.Model):null_demo = models.CharField(null=True, max_length=200)blank_demo = models.CharField(blank=True, max_length=200)null_or_blank_demo = models.CharField(null=True, blank=True, max_length=200)

说明

  • null:默认为 False;设为 True 时,表示字段在数据库中可以存储 NULL 值。
  • blank:默认为 False;设为 True 时,表示在 Django 表单(如 Admin 后台)中可以留空。

blank=True 时,存入数据库的值依赖于 null 的设置:

  • null=True 时,留空会存入 NULL
  • null=False 或默认时,留空会存入空字符串 ''

nullblank 结合使用的几种情况总结:

null=Falsenull=True
blank=False数据库中不可为 NULL
表单中必填
数据库中可为 NULL
表单中必填
blank=True数据库中不可为 NULL
表单中可不填;
⭐ 留空时存入 ''
数据库中可为 NULL
表单中可不填;
⭐ 留空时存入 NULL

通过合理使用 nullblank 的组合,可以根据需求控制数据库和表单的行为。

2、choices

choices 是一个映射或可迭代对象,用作模型字段的选项。

提供 choices 后,字段的默认表单小部件会变为选择框,并且选项会被模型验证强制执行。

choices 在 Django 中有以下几种形式:

(1) 简单的列表或元组形式

这是最常见的形式,choices 定义为一个包含 (值, 可读名称) 的列表或元组。适用于定义一组固定的选项。

# 1、列表形式 (定义在模型类之外)
YEAR_IN_SCHOOL_CHOICES = [("FR", "Freshman"),("SO", "Sophomore"),("JR", "Junior"),("SR", "Senior"),("GR", "Graduate"),
]
# 2、元组形式 (定义在模型类之外)
# YEAR_IN_SCHOOL_CHOICES = (
#    ("FR", "Freshman"),
#    ("SO", "Sophomore"),
#    ("JR", "Junior"),
#    ("SR", "Senior"),
#    ("GR", "Graduate"),
#)
class Student(models.Model):# 3、列表/元组形式(定义在模型类内部,即将选项列表定义为类常量)# YEAR_IN_SCHOOL_CHOICES = [#     ("FR", "Freshman"),#     ("SO", "Sophomore"),#     ("JR", "Junior"),#     ("SR", "Senior"),#     ("GR", "Graduate"),# ]year_in_school = models.CharField(max_length=2,choices=YEAR_IN_SCHOOL_CHOICES,default="FR",)
(2) 字典映射形式

在 Django 5.0 中,choices 支持使用字典定义,每个键表示实际存储的值,值为可读名称。适合需要清晰键值对的场景。

# 1、定义在模型类之外
YEAR_IN_SCHOOL_CHOICES = {"FR": "Freshman","SO": "Sophomore","JR": "Junior","SR": "Senior","GR": "Graduate",
}
class Student(models.Model):# 2、定义在模型类内部# YEAR_IN_SCHOOL_CHOICES = {#     "FR": "Freshman",#     "SO": "Sophomore",#     "JR": "Junior",#     "SR": "Senior",#     "GR": "Graduate",# }year_in_school = models.CharField(max_length=2,choices=YEAR_IN_SCHOOL_CHOICES,default="FR",)
(3) 分组形式

通过嵌套元组或字典分组的方式,将选项分为不同类别,适用于多级选择的场景。

# 1、使用嵌套元组 (定义在模型类之外)
MEDIA_CHOICES = [("Audio", [("vinyl", "Vinyl"), ("cd", "CD")]),("Video", [("vhs", "VHS Tape"), ("dvd", "DVD")]),("unknown", "Unknown"),
]# 2、使用字典 (定义在模型类之外)
# MEDIA_CHOICES = {
#    "Audio": {"vinyl": "Vinyl", "cd": "CD"},
#    "Video": {"vhs": "VHS Tape", "dvd": "DVD"},
#    "unknown": "Unknown",
#}
class Media(models.Model):# 3、使用嵌套元组 (定义在模型类内部)# MEDIA_CHOICES = [#     ("Audio", [("vinyl", "Vinyl"), ("cd", "CD")]),#     ("Video", [("vhs", "VHS Tape"), ("dvd", "DVD")]),#     ("unknown", "Unknown"),# ]media_type = models.CharField(max_length=10,choices=MEDIA_CHOICES,default="unknown",)
(4) 可调用对象

choices 定义为一个无参可调用对象(如函数),函数返回一个合法的 choices 结构(例如列表或字典)。适合动态生成选项的场景。

def get_currencies():return {i: i for i in ["USD", "EUR", "JPY"]}class Expense(models.Model):currency = models.CharField(max_length=3, choices=get_currencies)
(5)枚举类型

使用 Django 的 TextChoicesIntegerChoices 等枚举类来定义 choices,适合需要常量化、易读性高的选择项。Django 自动生成 .choices.labels.values 等属性,便于管理。

class Student(models.Model):class YearInSchool(models.TextChoices):FRESHMAN = "FR", "Freshman"SOPHOMORE = "SO", "Sophomore"JUNIOR = "JR", "Junior"SENIOR = "SR", "Senior"GRADUATE = "GR", "Graduate"year_in_school = models.CharField(max_length=2, choices=YearInSchool.choices)
(6) 自定义数据类型的枚举

Choices 类的基础上扩展,可以将 choices 与特定数据类型(如 datedatetime)结合,适合需要特定类型支持的场景,如日期 date

import datetimeclass MoonLandings(datetime.date, models.Choices):APOLLO_11 = 1969, 7, 20, "Apollo 11 (Eagle)"APOLLO_12 = 1969, 11, 19, "Apollo 12 (Intrepid)"

这里仅介绍了处理 date类型的choices,关于其他自定义数据类型的枚举,请看本专栏文章【 关于Django 模型字段 choices自定义数据类型的枚举——补充】


综上,Django 中的 choices 形式主要有以上 6 种。

3. 基本 数据库 相关选项 (db_column、db_comment、db_default、db_index、db_tablespace)

  • db_column:指定字段在数据库中的列名,默认使用字段名。
  • db_comment:为数据库列添加注释,方便有数据库访问权限但无 Django 代码访问权限的用户了解字段含义。

db_column 、db_comment 举例:

from django.db import models
from django.utils import timezone
from django.db.models import F
from django.db.models.functions import Now, TruncMonth
from datetime import timedeltaclass Article(models.Model):title = models.CharField(max_length=200, db_column="article_title",   # 自定义数据库列名,如果不指定 db_column,列名将默认使用字段名,也就是 title。db_comment="文章标题",  # 数据库列注释)
  • db_default(Django 5.0 新增):在数据库层面设置字段的默认值,可以是常量或数据库函数。注意,不能引用其他字段或模型。

    from django.db import models
    from django.utils import timezone
    from django.db.models import F
    from django.db.models.functions import Now, TruncMonth
    from datetime import timedeltaclass Article(models.Model):    # 设置数据库默认值:使用数据库函数created_at = models.DateTimeField(db_default=Now(),   # 使用数据库层面的 Now 函数作为默认值)# 设置数据库默认值:使用复杂的数据库表达式-->设置为"当前日期" 90 天后的月份的第一天due_date = models.DateField(db_default=TruncMonth(Now() + timedelta(days=90), output_field=models.DateField()))
    
  • db_index:设置为 True 时,创建数据库索引。建议使用 Meta.indexes 替代。

  • db_tablespace:用于指定字段索引存放的数据库表空间。简单来说,它可以将字段的索引存储在特定的物理位置,从而实现更高效的数据库管理和性能优化。此选项仅在支持表空间的数据库(如 PostgreSQL、Oracle)中有效。

db_index 、db_tablespace 举例:

from django.db import models
from django.utils import timezone
from django.db.models import F
from django.db.models.functions import Now, TruncMonth
from datetime import timedeltaclass Article(models.Model):   # 设置字段的索引,且使用表空间pub_date = models.DateTimeField(db_index=True,  # 为字段创建数据库索引db_tablespace="custom_tablespace"  # 使用自定义表空间)

4. 默认值与编辑选项(default、editable)

  • default:设置字段的默认值,可以是固定值或动态生成的值。对于不可变对象,直接使用;对于可变对象,必须使用函数。

    from django.db import models
    from django.utils import timezoneclass ExampleModel(models.Model):# 1. 固定值:使用固定值作为默认值status = models.CharField(max_length=20,default="Draft"  # 设置固定字符串作为默认值)# 2. 函数/可调用对象:使用函数或或可调用对象生成动态默认值(例如当前时间)created_at = models.DateTimeField(default=timezone.now  # 使用当前时间作为默认值)# 3. 不可变和可变对象:对不可变对象可以直接使用;#    对于可变对象(如列表或字典),必须使用函数包装来避免所有实例共享同一对象。settings = models.JSONField(default=lambda: {"theme": "light", "notifications": True}  # 使用函数生成默认值)
  • editable:决定字段是否在表单和管理后台中显示。对于只读或自动生成的字段,通常设为 False

    class Article(models.Model):# 1. 默认(editable=True):该字段会出现在管理后台和表单中,可以编辑。title = models.CharField(max_length=200,default="Untitled Article",  # 默认值,可编辑editable=True  # 可以编辑)# 2. 设为不可编辑,该字段不会出现在管理后台或 ModelForm 表单中,也不会进行表单验证,通常用于只读或自动生成的字段。description = models.TextField(default="No description provided.",  # 默认值,不可编辑editable=False  # 不会出现在表单中)
    

5. 错误消息与帮助文本(error_messages、help_text)

  • error_messages:指定字段验证时的错误信息,接受 nullblankinvalidunique 等键值字典,覆盖默认错误消息。

    from django.db import modelsclass UserProfile(models.Model):# 用户名字段自定义错误消息username = models.CharField(max_length=50,unique=True,  # 设置唯一性约束"""blank:当表单提交时,若 username 为空,返回“用户名不能为空,请输入您的用户名。”。unique:若 username 值重复,返回“此用户名已被使用,请选择其他用户名。”。null:当数据库层面该字段值为 NULL 时,返回“用户名不能为空值。”。invalid:若 username 格式不符合要求(例如设置了其他验证器),返回“用户名格式不正确,请检查输入。”。"""error_messages={'blank': "用户名不能为空,请输入您的用户名。",'unique': "此用户名已被使用,请选择其他用户名。",'null': "用户名不能为空值。",'invalid': "用户名格式不正确,请检查输入。"})# 邮箱字段自定义错误消息email = models.EmailField("""若邮箱为空,提示“邮箱不能为空,请输入您的邮箱地址。”。若邮箱格式不符合要求,提示“邮箱格式不正确,请输入有效的邮箱地址。”。"""error_messages={'blank': "邮箱不能为空,请输入您的邮箱地址。",'invalid': "邮箱格式不正确,请输入有效的邮箱地址。"})
  • help_text:提供额外的帮助文本,通常用于表单中。可以使用 HTML,但需注意转义。

    from django.db import modelsclass Product(models.Model):name = models.CharField(max_length=100,help_text="请输入产品名称,不超过100个字符。")
    

    在这里插入图片描述


6. 唯一性选项(primary_key、unique、unique_for_date、unique_for_month、unique_for_year)

  • primary_key:若为 True,则该字段作为模型的主键。主键字段默认为 null=Falseunique=True。Django 默认会创建一个主键字段,除非手动指定。

  • unique:若为 True,则字段值必须在整个表中唯一。数据库和模型验证都会强制执行。

  • unique_for_dateunique_for_monthunique_for_year:限定字段值在指定日期、月份或年份内唯一。适用于日期和时间字段,依赖 Model.validate_unique() 验证。

    举例:假设我们有一个新闻文章模型 Article,其中每篇文章的标题在同一发布日期内必须唯一。通过 unique_for_dateunique_for_monthunique_for_year 来实现这一需求。

    from django.db import modelsclass Article(models.Model):title = models.CharField(max_length=200)pub_date = models.DateField()  # 发布日期字段# 设置 title 在特定时间段内唯一unique_for_day_title = models.CharField(max_length=200,unique_for_date="pub_date",  # 在同一天内,title 必须唯一)unique_for_month_title = models.CharField(max_length=200,unique_for_month="pub_date",  # 在同一个月内,title 必须唯一)unique_for_year_title = models.CharField(max_length=200,unique_for_year="pub_date",  # 在同一年内,title 必须唯一)
    

    注意

    • 非数据库层面:这些约束仅在 Django 的模型层面生效,在数据库层面不会强制执行。

    • 需要日期字段支持:这些约束依赖于 DateFieldDateTimeField 类型的日期字段,必须在同一个模型中定义。

    • 仅在 ORM 中生效:这些唯一性约束只在 Django ORM 中保存数据时有效,直接在数据库中插入数据时不会验证。

    • 不适用于被表单排除的字段:如果日期字段在表单中被排除或不可编辑,Django 无法验证该唯一性约束。常见的“排除”方式有以下几种:

      • ①在表单的 exclude 选项中指定字段

        from django import forms
        from .models import Articleclass ArticleForm(forms.ModelForm):class Meta:model = Articlefields = ['title', 'content']  # 只包含 'title' 和 'content'exclude = ['pub_date']  # 排除 'pub_date' 字段
        
      • ② 在 fields 中仅指定需要的字段

        class ArticleForm(forms.ModelForm):class Meta:model = Articlefields = ['title', 'content']  # 仅包括 'title' 和 'content' 字段
      • ③ 将字段设为不可编辑(editable=False

        from django.db import modelsclass Article(models.Model):title = models.CharField(max_length=200)content = models.TextField()pub_date = models.DateField(editable=False)  # 设置为不可编辑

7. 其他选项(verbose_name、validators、自定义验证器)

  • verbose_name:字段的可读名称,若不设置,Django 会自动使用字段名(将下划线转换为空格)。例如,first_name 字段默认会显示为 “First name”。

    from django.db import modelsclass Product(models.Model):# 设置了 verbose_namename = models.CharField(max_length=100,verbose_name="产品名称"  # 字段显示为“产品名称”)# 未设置 verbose_name,Django 使用字段名,自动替换下划线为空格product_code = models.CharField(max_length=20)  # 显示为“Product code”# 使用 gettext_lazy 进行国际化description = models.TextField(verbose_name=_("Product Description")  # 支持多语言的字段名)
    

在这里插入图片描述

:关于 gettext_lazy 国际化,欢迎查看【Django 启用国际化支持—实现配置多国语言-CSDN博客】

  • validators:字段的验证器列表,可包含自定义的验证函数或预定义的验证器。

    Django 提供了一些常用的内置验证器,常见的有:

    • MaxValueValidator:检查值是否不超过指定的最大值。
    • MinValueValidator:检查值是否不低于指定的最小值。
    • MaxLengthValidator:检查文本字段的最大长度。
    • MinLengthValidator:检查文本字段的最小长度。
    • EmailValidator:检查字段是否是有效的电子邮件地址。
    • URLValidator:检查字段是否是有效的 URL 地址。
    • RegexValidator:使用正则表达式检查字段格式。

    示例代码:

    from django.db import models
    from django.core.validators import MaxValueValidator, MinValueValidator, EmailValidator, RegexValidatorclass UserProfile(models.Model):# 年龄字段,要求在 0 到 120 之间age = models.IntegerField(validators=[MinValueValidator(0), MaxValueValidator(120)])# 邮箱字段,验证邮箱格式email = models.EmailField(validators=[EmailValidator(message="请输入有效的邮箱地址")])# 手机号字段,使用正则表达式验证手机号格式phone_number = models.CharField(max_length=15,validators=[RegexValidator(regex=r'^\+?1?\d{9,15}$', message="请输入有效的手机号")])

    在这里插入图片描述

    自定义验证器示例

    自定义验证器是一个函数或可调用对象,它接收一个值作为参数并验证该值。如果验证失败,需要抛出 ValidationError 异常。自定义验证器可以实现更加灵活、复杂的规则。

    示例代码:

    from django.core.exceptions import ValidationError
    from django.core.validators import MinLengthValidator, MaxLengthValidator
    import re# 自定义验证器函数
    """
    假设我们想确保用户名不能包含特殊字符,且长度限制在 5 到 30 个字符之间,可以编写一个自定义验证器:
    """
    def validate_username(value):if not re.match(r'^[a-zA-Z0-9_]+$', value):raise ValidationError("用户名只能包含字母、数字和下划线")class User(models.Model):username = models.CharField(max_length=30,validators=[validate_username, # 应用自定义验证器MinLengthValidator(5),MaxLengthValidator(30)]  )

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/59679.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++清除所有输出【DEV-C++】所有编辑器通用 | 算法基础NO.1

各位小伙伴们,上一期的保留小数位数教学够用一辈子,有不错的点赞量,可我连一个粉丝铁粉都没有,你愿意做我的第一个铁粉吗?OK废话不多说,开始! 温故与知心 可能你也学过,且是工作者…

【提高篇】3.3 GPIO(三,工作模式详解 上)

目录 一,工作模式介绍 二,输入浮空 2.1 输入浮空简介 2.2 输入浮空特点 2.3 按键检测示例 2.4 高阻态 三,输入上拉 3.1 输入上拉简介 3.2 输入上拉的特点 3.3 按键检测示例 四,输入下拉 4.1 输入下拉简介 4.2 输入下拉特点 4.3 按键检测示例 一,工作模式介绍…

Thinkphp6视图介绍

一.MVC MVC 软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller) ThinkPHP6 是一个典型的 MVC 架构 控制器—控制器,用于将用户请求转发给相应的Model进行处理&a…

C++(Qt)软件调试---内存泄漏分析工具MTuner (25)

C(Qt)软件调试—内存泄漏分析工具MTuner (25) 文章目录 C(Qt)软件调试---内存泄漏分析工具MTuner (25)[toc]1、概述🐜2、下载MTuner🪲3、使用MTuner分析qt程序内存泄漏🦧4、相关地址&#x1f41…

QT_CONFIG宏使用

时常在Qt代码中看到QT_CONFIG宏,之前以为和#define、DEFINES 差不多,看了定义才发现不是那么回事,定义如下: 看注释就知道了QT_CONFIG宏,其实是:实现了一个在编译时期安全检查,检查指定的Qt特性…

Redis下载历史版本

Linux版本: https://download.redis.io/releases/ Windows版本: https://github.com/tporadowski/redis/releases Linux Redis对应gcc版本

8 软件项目管理

软件项目管理 1、软件项目管理概念1.1 软件项目管理内容1.2 软件项目管理的4P要素人员产品过程项目 2、软件项目度量2.1 软件项目度量定义及度量方法2.2 面对规模的度量2.3 面对功能的度量UFC相关的五类组件14个复杂性调节因素 F i F_i Fi​一个功能点开发代码行数 2.4 软件估算…

游戏引擎学习第12天

视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西,主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数(或 alloca)分配的是栈内存,它的特点是: 生命周…

如何保证Redis与MySQL双写一致性

什么是双写一致性问题? 双写一致性主要指在一个数据同时存在于缓存(如Redis)和持久化存储(如MySQL)的情况下,任何一方的数据更新都必须确保另一方数据的同步更新,以保持双方数据的一致状态。这一…

STM32设计学生宿舍监测控制系统

目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 电路图采用Altium Designer进行设计: 三、实物设计图 四、程序源代码设计 五、获取资料内容 前言 随着科技的飞速发展和智能化时代的到来,学生宿舍的安全、舒适…

算法--解决二叉树遍历问题

第一 实现树的结构 class Node(): # 构造函数,初始化节点对象,包含数据和左右子节点 def __init__(self, dataNone): self.data data # 节点存储的数据 self.left None # 左子节点,默认为None self.rig…

【C#】C#编程入门指南:构建你的.NET开发基础

文章目录 前言:1. C# 开发环境 VS的基本熟悉2. 解决方案与项目的关系3. 编辑、编译、链接、运行4. 托管代码和CLR4.1 CLR:4.2 C# 代码第编译过程(两次编译的) 5. 命名空间6. 类的组成与分析7. C# 的数据类型7.1 值类型7.2 引用类型…

算法闭关修炼百题计划(八)

一半来自力扣的push题单 1.最大连续1的个数II2.长度为k的无重复字符子串3.句子的相似性4.移位字符串分组5.x的平方根6.Z字形变换 1.最大连续1的个数II 给定一个二进制数组nums,如果最多可以翻转一个0,则返回数组中连续1的最大个数 之前是Window&#x…

论文笔记(五十六)VIPose: Real-time Visual-Inertial 6D Object Pose Tracking

VIPose: Real-time Visual-Inertial 6D Object Pose Tracking 文章概括摘要I. INTRODACTIONII. 相关工作III. APPROACHA. 姿态跟踪工作流程B. VIPose网络 文章概括 引用: inproceedings{ge2021vipose,title{Vipose: Real-time visual-inertial 6d object pose tra…

K8S containerd拉取harbor镜像

前言 接前面的环境 K8S 1.24以后开始启用docker作为CRI,这里用containerd拉取 参考文档 正文 vim /etc/containerd/config.toml #修改内容如下 #sandbox_image "registry.aliyuncs.com/google_containers/pause:3.10" systemd_cgroup true [plugins.…

LM2 : A Simple Society of Language Models Solves Complex Reasoning

文章目录 题目摘要简介相关工作方法论实验结果结论局限性 题目 LM2:简单的语言模型社会解决复杂推理问题 论文地址:https://aclanthology.org/2024.emnlp-main.920/ 项目地址: https://github.com/LCS2-IIITD/Language_Model_Multiplex 摘要…

STM32从上电开始启动过程详解(上电->分散加载->main函数)

1.硬件复位之后,CPU 内的时序逻辑电路首先完成如下两个工作( 程序代码下载到内部 flash 为例,flash首地址 0x0800 0000)  将 0x08000000 位置存放的堆栈栈顶地址存放到 SP 中(MSP)。  将 0x08000004 位置存放的向量地址装入 P…

新版Apache tomcat服务安装 Mac+Window双环境(笔记)

简介:Tomcat服务器器的下载和安装: 安装前提 1)电脑需要有java环境,jdk8以上,否则启动不不成功 2)已经安装Sublime⽂文件编辑软件 3)window电脑需要显示⽂文件拓拓展名 官网(https:…

数据重塑:长宽数据转换【基于tidyr】

在数据分析和可视化过程中,数据的组织形式直接影响着我们能够进行的分析类型和可视化效果。这里简单介绍两种常见的数据格式:长格式(Long Format)和宽格式(Wide Format),以及如何使用tidyr包进行…

ollama+springboot ai+vue+elementUI整合

1. 下载安装ollama (1) 官网下载地址:https://github.com/ollama/ollama 这里以window版本为主,下载链接为:https://ollama.com/download/OllamaSetup.exe。 安装完毕后,桌面小图标有一个小图标,表示已安装成功&…