Django Web架构:全面掌握Django模型字段(上)

news2024/11/18 9:35:37
Django Web架构
全面掌握Django模型字段(上)

- 文章信息 - Author: 李俊才 (jcLee95)
Visit me at CSDN: https://jclee95.blog.csdn.net
My WebSitehttp://thispage.tech/
Email: 291148484@163.com.
Shenzhen China
Address of this article:https://blog.csdn.net/qq_28550263/article/details/136380968
HuaWei:https://bbs.huaweicloud.com/blogs/422970

【介绍】:在开发Django应用时,模型字段扮演着至关重要的角色。它们不仅定义了数据的结构,即数据库表的列,还规定了数据的行为和如何与之交互。通过精心设计的模型字段,开发者可以在数据库和应用层之间建立起一座桥梁,使得数据的存取、验证和处理变得既高效又安全。


下一节:《 全面掌握Django模型字段(下)

在这里插入图片描述


1. 概述

在开发Django应用时,模型字段扮演着至关重要的角色。它们不仅定义了数据的结构,即数据库表的列,还规定了数据的行为和如何与之交互。通过精心设计的模型字段,开发者可以在数据库和应用层之间建立起一座桥梁,使得数据的存取、验证和处理变得既高效又安全。

1.1 Django模型字段的核心作用

Django模型字段的核心作用在于其能够明确地定义数据的类型、约束和行为。这不仅有助于数据库层面上的数据完整性保护,还能在应用层面上提供丰富的数据处理能力。例如,通过设置null和blank选项,我们可以控制字段的必填性;通过choices选项,我们可以限制字段的取值范围,等等。

1.2 字段与数据交互

模型字段的设计直接影响到数据的读写方式。Django提供了丰富的字段类型和选项,使得开发者可以根据实际需求灵活地处理各种数据类型,如文本、数字、日期时间等。此外,Django的模型字段还支持高级数据结构,如JSON字段,以及与其他模型的关系字段,如外键(ForeignKey)、多对多关系(ManyToManyField)等,极大地丰富了数据交互的可能性。

1.3 文章目标与读者

本文旨在为读者提供一个系统而全面的指南,帮助读者深入理解 Django 模型字段的各个方面,包括字段的类型、选项、与数据库及表单的交互方式,以及如何利用字段的高级特性来满足复杂的数据处理需求。无论是Django新手还是有一定经验的开发者,都可以从中获得有价值的知识和技巧。

通过本文的学习,读者将能够:

  • 理解Django模型字段的基本概念和作用
  • 掌握常用字段类型及其应用场景
  • 熟悉字段选项的含义和使用方法
  • 学会如何通过模型字段与数据库和表单进行有效的数据交互
  • 探索字段的高级特性,如关系字段和自定义字段
  • 通过实践案例加深对模型字段应用的理解

本文的目标是帮助读者构建出既健壮又灵活的Django应用,充分利用Django框架提供的强大功能,提升开发效率和应用质量。

2. 字段类型与选项

2.1 字段类型

在Django中,模型字段类型决定了数据如何在数据库中存储,以及如何通过Python代码进行访问和处理。每种字段类型都有其特定的用途和应用场景。

2.1.1 常用字段

以下是一些常用字段类型的介绍和使用示例。

CharField:

用于存储短或长字符串。它必须定义max_length参数,指定字符的最大长度。适用于存储如姓名、标题等较短的文本。

class Person(models.Model):
    name = models.CharField(max_length=100)
IntegerField:

用于存储整数。适用于存储年龄、数量等整数值。

class Product(models.Model):
    quantity = models.IntegerField()
DateField 和 DateTimeField

DateField用于存储日期,而DateTimeField用于存储日期和时间。这两种字段类型对于记录事件发生的日期或时间非常有用。

class Event(models.Model):
    date = models.DateField()
    timestamp = models.DateTimeField()

2.1.2 特殊字段类型

枚举类型:

Django 3.0 开始引入了枚举类型的支持,允许开发者以更清晰和结构化的方式定义字段的选择。枚举类型通过子类化models.TextChoices、models.IntegerChoices或models.Choices来实现。

from django.db import models

class Student(models.Model):
    # 定义枚举类型表示学生所在年级
    class YearInSchool(models.TextChoices):
        FRESHMAN = 'FR', 'Freshman'   # 新生
        SOPHOMORE = 'SO', 'Sophomore' # 大二
        JUNIOR = 'JR', 'Junior'       # 大三
        SENIOR = 'SR', 'Senior'       # 大四

    # 使用 CharField 表示学生所在年级,设置 choices 参数为 YearInSchool.choices,default 参数为 YearInSchool.FRESHMAN
    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool.choices,
        default=YearInSchool.FRESHMAN,
    )
自定义字段

当内置的字段类型无法满足特定需求时,可以通过继承models.Field类来创建自定义字段。这允许开发者定义自己的数据类型,以及如何将Python值转换为数据库值,反之亦然。

# 自定义字段,表示以逗号分隔的整数列表字段
class CommaSeparatedIntegerField(models.Field):
    # 初始化方法
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    # 从数据库值转换为 Python 值
    def from_db_value(self, value, expression, connection):
        if value is None:
            return value
        return [int(i) for i in value.split(',')]

    # 将 Python 值转换为数据库值
    def to_python(self, value):
        if isinstance(value, list):
            return value
        if value is None:
            return value
        return [int(i) for i in value.split(',')]

    # 获取准备存储到数据库的值
    def get_prep_value(self, value):
        return ','.join(str(i) for i in value)

    # 返回数据库中该字段的类型
    def db_type(self, connection):
        return 'text'

通过上述示例,我们可以看到Django模型字段类型的多样性和灵活性。选择正确的字段类型不仅可以确保数据以合适的格式存储,还可以提高数据处理的效率和准确性。

2.2 字段选项

2.2.1 字段选项概述

在Django模型中,字段选项允许开发者定义数据的行为和约束,这些选项对于数据验证、数据库设计以及用户界面的呈现至关重要。

下面的表格展示了 Django 中通用字段选项的含义、默认值,以及注意事项。

选项名称描述默认值特别注意事项
null如果为True,允许字段在数据库中存储NULL值False避免在基于字符串的字段上使用。对于字符串字段,使用空字符串而不是NULL。
blank如果为True,字段在表单验证时可以为空False与null不同,blank影响的是表单验证而非数据库存储。
choices为字段定义一组选项。选项可以是映射、可迭代对象或可调用对象,用于模型验证和表单小部件Django 5.0添加了对映射和可调用对象的支持。
db_column指定数据库中的列名字段名如果数据库列名是SQL保留字或包含非法字符,Django会自动处理。
db_comment为数据库列添加注释Django 4.2中新增。
db_default指定字段的数据库默认值Django 5.0中新增。可以是字面值或数据库函数。
db_index如果为True,为字段创建数据库索引False推荐使用Meta.indexes选项代替。
db_tablespace指定字段索引的数据库表空间名默认项目的DEFAULT_INDEX_TABLESPACE设置如果后端不支持索引的表空间,则忽略此选项。
default字段的默认值可以是值或可调用对象。默认值不能是可变对象。
editable如果为False,字段不会在管理界面或任何ModelForm中显示True也会在模型验证中跳过。
error_messages覆盖字段引发的默认错误消息键包括null、blank、invalid等。
help_text字段的额外帮助文本,随表单控件显示在自动生成的表单中,此值不是HTML转义的。
primary_key如果为True,将字段设置为模型的主键Falseprimary_key=True意味着null=False和unique=True。
unique如果为True,字段值在整个表中必须唯一False在数据库级别和模型验证中强制执行。
unique_for_date设置为DateField或DateTimeField的名称,要求字段的日期值是唯一的在模型验证中强制执行,但不在数据库级别执行。
unique_for_month要求字段对月份是唯一的类似于unique_for_date。
unique_for_year要求字段对年份是唯一的类似于unique_for_date和unique_for_month。
verbose_name字段的人类可读名称由字段的属性名自动创建Django会将属性名中的下划线转换为空格。
validators要为该字段运行的验证器列表参见Django验证器相关资料。

接下来对一些常用的 字段选项展开进行讲解。

2.2.2 null

null是一个布尔值选项,用于指定数据库中字段是否可以存储NULL值。默认情况下,null 设置为 False,意味着数据库中的字段不允许存储NULL 值。

【注意】:在基于字符串的字段上使用 null=True可能导致数据一致性问题。Django 官方推荐使用空字符串来表示没有数据,而非NULL

应用场景null=True 通常用于非字符串字段,如 DateFieldForeignKey 等,以允许字段在数据库中存储 NULL 值,表示没有数据。对于字符串字段(CharFieldTextField),建议避免使用 null=True,以防止出现两种表示“无数据”的情况(NULL和空字符串)。

例如:

class UserProfile(models.Model):
    bio = models.TextField(null=True)

在这个示例中,bio字段被设置为null=True,这意味着用户的个人简介(bio)是可选的,在数据库中可以存储为NULL,表示用户没有提供个人简介。这对于非字符串字段(如日期、时间、关系字段等)特别有用,因为它们在没有值时自然对应于NULL。

2.2.3 blank

blank也是一个布尔值选项,与null不同,blank影响的是数据的验证,而非数据库层面的约束。blank=True表示字段在表单验证时可以为空。

【提示】blanknull的区别在于,blank影响的是表单验证,而null影响的是数据库存储。正确地使用这两个选项对于保证数据的完整性和一致性至关重要。

应用场景:blank=True常用于表单中,允许用户不填写某些字段。例如,一个可选的联系电话字段可以设置为blank=True。需要注意的是,即使字段设置为blank=True,如果没有同时设置null=True,在数据库层面仍然不能存储NULL值。

例如:

class Order(models.Model):
    special_instructions = models.TextField(blank=True)

在这个示例中,special_instructions字段被设置为blank=True,这意味着在表单验证时,用户可以不提供特别指令。这对于创建用户友好的表单非常有用,允许用户提交表单时留下某些字段为空。

2.2.4 choices

choices 选项允许为字段预定义一组选项,这些选项将在Django的管理界面和表单中以下拉列表的形式展现。choices 接受一个二元组的序列,每个二元组包含两个元素:存储在数据库中的实际值和在界面上显示的可读名称。

【提示】虽然choices提供了一种便捷的方式来限制字段的可能值,并在用户界面上提供了友好的选项列表,但它并不影响数据库层面的数据验证。因此,确保数据库中的数据符合choices定义的约束还需要其他机制,如模型的clean方法或自定义验证逻辑。

应用场景choices 非常适合表示状态、类型、等级等有限选项的字段。例如,定义一个学生模型的年级字段时,可以使用 choices 来限制年级的选项。

例如:

class Student(models.Model):
    class YearInSchool(models.TextChoices):
        FRESHMAN = 'FR', _('Freshman')
        SOPHOMORE = 'SO', _('Sophomore')
        JUNIOR = 'JR', _('Junior')
        SENIOR = 'SR', _('Senior')

    year_in_school = models.CharField(
        max_length=2,
        choices=YearInSchool.choices,
        default=YearInSchool.FRESHMAN,
    )

在这个示例中,year_in_school字段使用了choices选项来限制可以选择的值。这确保了数据的一致性,并在用户界面上提供了一个下拉列表,让用户从预定义的选项中选择。

choices 选项通过限制字段可以接受的值来增强数据的一致性和可靠性。在Django管理界面和表单中,choices 会自动转换为下拉列表,提高用户体验。

虽然choices 在用户界面上限制了输入,但它并不强制数据库层面的数据一致性,因此在某些情况下可能需要额外的验证逻辑来确保数据的有效性。

2.2.5 default

default 选项用于为字段指定一个默认值。当创建模型实例而未指定该字段的值时,将自动填充此默认值。

【提示】默认值不应该是可变对象(如列表或字典),因为可变默认值可能导致意外的行为。如果需要动态计算默认值,可以将一个可调用对象(如函数)作为default的值。

应用场景:适用于需要预设初始值的场景,如注册时间字段可以设置为当前时间default=timezone.now,或者新用户的激活状态默认为 False

例如:

from django.utils import timezone

class Article(models.Model):
    published_date = models.DateTimeField(default=timezone.now)

在这个示例中,published_date字段被设置了一个默认值timezone.now,这意味着当创建一个新的Article实例而没有指定published_date时,它会自动使用当前时间作为默认值

2.2.6 editable

editable 决定字段是否在 Django 管理界面或 ModelForm 中显示。如果设置为 False,该字段将不会显示在表单中,但仍然可以通过代码修改。

【注意】即使字段设置为editable=False,在模型的clean方法和其他模型验证中仍然会处理这些字段。因此,需要确保即使字段不可编辑,其值也符合模型的逻辑和约束。

应用场景:适用于不希望用户直接编辑,但在模型内部逻辑中需要的字段,如自动计算的得分或状态字段。

例如:

class Payment(models.Model):
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    processed = models.BooleanField(default=False, editable=False)

在这个示例中,processed字段被设置为editable=False,这意味着在Django管理界面或任何由ModelForm自动生成的表单中,这个字段不会显示,防止用户直接修改支付的处理状态。然而,这个字段仍然可以在模型的逻辑中被程序修改。

2.2.7 primary_key

primary_key=True 将字段设置为模型的主键。每个模型都需要有一个主键字段, Django 默认使用自增的 IntegerField 作为主键。

【注意】设置 primary_key=True 意味着 null=Falseunique=True。一个模型只能有一个主键字段。

应用场景:当需要使用非自增字段作为模型的唯一标识时使用,如使用UUID字段作为主键。

例如:

import uuid
from django.db import models

class MyModel(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

在这个示例中,id字段被设置为模型的主键,并使用UUID作为默认值。primary_key=True意味着这个字段是模型的唯一标识符,而default=uuid.uuid4确保每个实例在创建时都会被分配一个唯一的UUID。

2.2.8 verbose_name

verbose_name 为字段提供一个人类可读的名称。如果未指定,Django 会自动从字段的名称生成(将下划线转换为空格)。

【提示】在定义模型字段时,通过 verbose_name 参数提供的名称会在 Django 管理界面和错误消息中使用,有助于提升用户体验。

应用场景:适用于需要提供更清晰字段说明的场景,特别是在管理界面中显示更友好的字段名。

例如:

class Person(models.Model):
    first_name = models.CharField(max_length=30, verbose_name="given name")

在这个示例中,first_name字段的verbose_name被设置为"given name",这在Django管理界面和表单中为字段提供了一个更易于理解的标签,而不是简单地使用字段的变量名。

verbose_name为模型字段提供了一个更人性化的名称,这在创建用户友好的管理界面和表单时非常有用。Django会自动使用这个名称在管理界面和错误消息中,提高了应用的可用性和可访问性。)

2.2.9 unique

unique=True为字段添加了一个唯一性约束,这在需要保证数据唯一性的字段(如用户名、电子邮件地址等)上非常有用。这个约束在数据库层面强制执行,尝试插入重复值将引发错误,保证了数据的一致性和准确性。

【提示】unique约束在数据库级别和模型验证中强制执行。在数据库层面,尝试插入重复值将引发错误。

应用场景:适用于需要保证数据唯一性的字段,如用户的电子邮件地址或身份证号码。

例如:

class User(models.Model):
    email = models.EmailField(unique=True)

在这个示例中,email字段被设置为unique=True,确保了数据库中不会有两个User实例具有相同的电子邮件地址。

2.2.10 db_column

db_column 允许指定字段在数据库中的列名。这在需要与已存在的数据库或遵循特定数据库命名约定时特别有用。

【提示】如果未指定db_column,Django将使用字段的名称作为数据库列名。在大多数情况下,保持Django的默认行为即可,除非需要解决数据库列名的特定问题。

应用场景:当模型字段的名称与数据库列名不一致时使用,或者当数据库列名是SQL保留字或包含非法字符时。

例如:

class ExampleModel(models.Model):
    attribute = models.CharField(max_length=100, db_column='custom_column_name')

在这个示例中,attribute字段在数据库中的列名被指定为custom_column_name,而不是Django默认的字段名attribute。

3. 结论

在本文中,我们深入探讨了 Django 模型字段的重要性以及其在开发中的核心作用。模型字段不仅定义了数据的结构,还规定了数据的行为和与之交互的方式。通过正确选择字段类型和选项,开发者能够建立起数据库和应用层之间的有效桥梁,实现数据的高效存取、验证和处理。

了解和熟练掌握 Django 模型字段是开发高质量 Web 应用的关键之一。通过不断学习和实践,我们相信读者可以在 Django 开发中取得更大的成就,并构建出健壮、灵活且易于维护的应用程序。

进阶:《Django Web架构:全面掌握Django模型字段(下)》

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

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

相关文章

数电学习笔记——逻辑函数及其描述方法

目录 一、逻辑函数 二、逻辑函数的描述方法 1、逻辑真值表 2、逻辑函数式 3、逻辑图 4、波形图 三、逻辑函数的两种标准形式 1、最小项与最大项 最小项 最小项的性质 最大项 最大项的性质 2、最大项与最小项的关系 3、逻辑函数的最小项之和形式 4、逻辑函数的最…

Unity(第二十四部)UI

在游戏开发中,用户界面(UI)是至关重要的一部分。它负责与玩家进行交互,提供信息,并增强游戏的整体体验。Unity 提供了强大的工具和功能来创建和管理 UI。 ui的底层就是画布,创建画布的时候会同时创建一个事…

k8s部署mysql

(作者:陈玓玏) 一、前置条件 已部署k8s,服务端版本为1.21.14 二、部署mysql 拉取镜像; docker pull mysql将账号密码等信息写到configmap,创建configmap; apiVersion: v1 kind: ConfigMap m…

C++笔记(五)--- 虚函数(virtual)

目录 虚函数介绍 虚函数、覆盖和重载区别 虚函数介绍 C的虚函数是多态性的表现 1.构造函数不能为虚函数2.子类继承时虚函数仍为虚函数3.虚函数类外实现时,不需要加virtual4.有虚函数的类,析构函数一定要写成虚函数(否则可能会造成内存泄漏&…

Docker实战——容器

目录 Docker 容器的基本概念与操作1.使用“docker create”创建容器。这里基于Nginx的镜像创建了一个容器,名字为mycontainer。2.使用“docker ps -a”命令查看所有的容器,这时的容器不一定是运行状态。3.使用 “docker start” 命令可以启动容器。4.使用…

SpringBoot整合rabbitmq-主题交换机队列(四)

说明:Topic主题交换机它的大致流程是交换机和一个或者多个队列绑定,这个绑定的Routingkey是包含通配符的,满足通配符的队列会接收到消息。 通配符规则: #:匹配一个或多个词 *:匹配一个词 例如&#xff…

android TextView 实现富文本显示

android TextView 实现富文本显示,实现抖音直播间公屏消息案例 使用: val tvContent: TextView helper.getView(R.id.tvContent)//自己根据UI业务要求,可以控制 图标显示 大小val levelLabel MyImgLabel( bitmap 自己业务上的bitmap )va…

Prometheus 安装指南

目录 介绍 安装 介绍 Prometheus是一款开源监控系统,适用于容器化和微服务。它使用多维数据模型,支持PromQL查询语言,可以通过多种方式采集数据。具备灵活的告警和通知机制,可集成图形工具创建仪表盘。通过本地存储高效保存时间…

ywtool check命令及ywtool clean命令

一.ywtool check命令 1.1 ywtool check -I 1.2 ywtool check all 1.3 ywtool check io 1.4 ywtool check elk 1.5 ywtool check php 1.6 ywtool check mysql 1.7 ywtool check nginx 1.8 ywtool check system 1.9 ywtool check docker_nbip [容器名称] 1.10 ywtool check 1.10…

buuctf_crypto_丢失的MD5+Quoted-printable+RSA

丢失的MD5 题目:(就一python文件,MD5.py) for i in range(32,127):for j in range(32,127):for k in range(32,127):mhashlib.md5()m.update(TASCchr(i)O3RJMVchr(j)WDJKXchr(k)ZM)desm.hexdigest()if e9032 in des and da in d…

吴恩达《机器学习》学习笔记

本笔记资料来源于 http://www.ai-start.com/ml2014/,该笔记来自于https://blog.csdn.net/dadapongi6/article/details/105668394,看了忘,忘了看,再看一遍。 时间统计:2024.2.29 5个番茄钟,从week1开始&…

游戏陪玩精品系统源码优化版3.0

下载地址:游戏陪玩精品系统源码优化版.zip 截图:

[Vulnhub]靶场 Web Machine(N7)

kali:192.168.56.104 主机探测: arp-scan -l 靶机ip:192.168.56.104 端口扫描 nmap -p- 192.168.56.106 看一下web 目录扫描 gobuster dir -u http://192.168.56.106 -x html,txt,php,bak,zip --wordlist/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt exp…

基于springboot实现街球社区网站系统项目【项目源码+论文说明】

基于springboot实现街球社区网站系统演示 摘要 本文主要讲述了基于SpringBootVue模式的街球社区网站的设计与实现。这里所谓的街球社区网站是通过类似于百度贴吧之类的网上论坛使得所有的街球爱好者有一个可以互相交流的平台,并使所有用户可以在社区进行教学视频的观看以及相关…

使用Fabric创建的canvas画布背景图片,自适应画布宽高

之前的文章写过vue2使用fabric实现简单画图demo,完成批阅功能;但是功能不完善,对于很大的图片就只能显示一部分出来,不符合我们的需求。这就需要改进,对我们设置的背景图进行自适应。 有问题的canvas画布背景 修改后的…

Python:练习:编写一个程序,写入一个美金数量,然后显示出如何用最少的20美元、10美元、5美元和1美元来付款

案例: python编写一个程序,写入一个美金数量,然后显示出如何用最少的20美元、10美元、5美元和1美元来付款: Enter a dollar amout:93 $20 bills: 4 $10 bills: 1 $5 bills:0 $1 bills:3 思考: 写入一个美金数量&…

leetcode 热题 100_字母异位词分组

题解一: 排序:对两个字母异位词,二者排序后的字符串完全一样,因此可以对所给字符串进行排序,以排序后的字符串作为HashMap哈希表的键值,将排序前的字符串作为值进行存储分组,最后返回。 import…

面试数据库篇(mysql)- 08事务

原理 事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败。 ACID是什么?可以详细说一下吗? 原子性(Atomicity):事务是不可分割的最小操作单元,要么全部成功,要么全…

element-ui附件上传及在线查看详细总结,后续赋源码

一、附件上传 1、在element-ui上面复制相应代码 a、accept"image/*,.pdf,.docx,.xlsx,.doc,.xls" 是规定上传文件的类型,若是不限制,可以直接将accept‘all即可; b、:action"action" 这个属性就是你的上传附件的地址&am…

全网首个GDB移植手册【Howto:Porting the GUN Debugger】翻译

Howto:Porting the GUN Debugger ✍【作者】:电子科大不知名程序员 📣【说明】:本文是自己在搭建mcore架构GDB时的参考的手册,具有很强的学习指导性,因原文档(链接:https://www.embecosm.com/a…