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废话不多说,开始! 温故与知心 可能你也学过,且是工作者…

Android 中的 Zygote 和 Copy-on-Write 机制详解

在 Android 系统中,Zygote 是一个关键的进程,几乎所有的应用进程都是通过它 fork(派生)出来的。通过 Zygote 启动新进程的方式带来了显著的性能优势,这得益于 fork 操作和 Linux 中的 Copy-on-Write(COW&am…

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

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

关于写React的一些反思和总结

这两个星期我都一直在写IT资产管理这个模块。关于这个模块,前端和后端都是我来处理,对于后端,我碰到了很多问题,但是很多问题都可以在比较短的时间内解决,而且不会说完全没有头绪的那种,这一方面源于我本身…

Mybatis中批量插入foreach优化

数据库批量入库方常见方式:Java中foreach和xml中使用foreach 两者的区别: 通过Java的foreach循环批量插入: 当我们在Java通过foreach循环插入的时候,是一条一条sql执行然后将事物统一交给spring的事物来管理(Transa…

Thinkphp6视图介绍

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

Ceph client 写入osd 数据的两种方式librbd 和kernel rbd

在Ceph存储系统中,客户端(Ceph client)写入OSD(Object Storage Daemon)数据确实可以通过两种主要方式:librbd和kernel rbd。这两种方式各有特点和适用场景,下面将分别进行详细介绍。 librbd方式…

基于大语言模型意图识别和实体提取功能;具体ZK数值例子:加密货币交易验证;

目录 基于大语言模型意图识别和实体提取功能 案例背景 零知识证明过程 具体例子 具体举例(简化) 具体ZK数值例子:加密货币交易验证 定义多项式 承诺 挑战 证明构造 证明验证 结论 zkLLM Zero Knowledge Proofs for Large Language Models 在大模型验证过程中处…

Python小游戏24——小恐龙躲避游戏

首先,你需要安装Pygame库。如果你还没有安装,可以通过以下命令安装: 【bash】 pip install pygame 【python】代码 import pygame import random # 初始化Pygame pygame.init() # 设置屏幕尺寸 screen_width 800 screen_height 600 screen …

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

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

【C#】第6章:用户界面设计 课后习题

文章目录 C# 控件知识详解一、选择题解析二、填充题解析 以下是一篇关于 C#中各类控件知识点的博客文章: C# 控件知识详解 在 C#编程中,各种控件起着至关重要的作用,它们为用户界面提供了丰富的交互功能。本文将详细介绍 C#中一些常见控件的…

QT_CONFIG宏使用

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

Python期末复习 | 列表、元组、字典、集合与字符串 | 代码演示

列表、元组、字典、集合与字符串 列表 ​ 列表是Python最重要的内置对象之一,是包含若干元素的有序连续内存空间。当列表增加或删除元素时,列表对象自动进行内存的扩展或收缩,从而保证相邻元素之间没有缝隙。 ​ 在形式上,列表…

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 引用类型…