Django表单系统

2023-10-27

目录

使用Form对象定义表单

Form对象的特性

表单字段的基类Field

常用的表单字段类型

基于Model定制的表单

ModelForm定义方式

表单中的常用方法


在Web站点中与后端服务进行交互,通常使用表单提交的方式。表单提交数据到达后端,首先要对数据做校验,对于不合法的数据需要拒绝并提示给前端,通过校验之后才能执行服务返回响应。由于所有的表单创建与处理流程都是相似的,所以,Django将这一过程抽象出来,形成表单系统。从在浏览器中显示表单到数据验证,再到对错误的处理,都可以由表单系统来完成。不仅如此,基于数据表(Model)创建表单也是很常见的情况,Django同样考虑到了这一点,并提供了ModelForm来简化功能实现。

使用Form对象定义表单

表单系统的核心是Form对象,它将表单中的字段封装成一系列Field和验证规则,以此来自动地生成HTML表单标签。

与其他对象的定义规则类似,可以将Form对象定义在任何位置。但是,Django的建议是将它们定义在应用下的forms.py文件中。这样做的原因是归类存储,

from django import forms

class titleform(forms.Form):
    title = forms.CharField(label='Topic title')

上面代码中,可以发现Form的定义与Model的定义非常相似,比较容易理解。这里的TopicSearchForm定义内容非常少。

  • Django规定,所有的Form对象都必须继承自django.forms.Form,所以这里的TopicSearchForm符合条件。
  • 定义了一个title属性,它是forms.CharField类型的Field,根据名称可以猜测此处将title指定为字符类型。label标签显式地指定了这个字段的名称,且Field有一个默认属性required为True,代表这个字段是必填的。

Form对象的特性

  • 实现对所有字段的验证
    • 每一个Form对象实例都会有一个is_valid方法,这个方法根据字段的定义验证实例的各个字段是否合法。如果所有的字段都是合法的,它会返回True,并且将数据存储到字典类型的cleaned_data属性中。
  • 根据字段定义生成HTML
    • 表单实例可以自动生成HTML表单元素,且默认输出使用HTML表格,但是并不提供<table>起始和结束标签。同时,也可以使用实例的as_ul方法获取列表形式的表单或使用as_p方法获取段落形式的表单。
    • 由于表单实例可以直接返回HTML表单元素,所以,可以用它来替换模板文件中的字段定义。更方便的是,在没有正确填充表单时,它还可以返回错误信息的提示。

表单字段的基类Field

基类Field定义于django/forms/fields.py文件中,这里重点关注它的构造函数中定义的属性以及校验给定字段值是否有效的clean方法。

  • required
    • 设定当前的Field是否是必须提供的,默认值是True,即必须提供。
  • widget
    • 指定在页面中显示字段的控件,可以是Widget类或者Widget类实例。对于大多数情况,默认的控件使用TextInput。
  • label
    • 指定在页面中显示的字段的名称(标签)提示。如果不指定的话,则页面中将直接显示字段定义的变量名(首字母大写)。
  • initial
    • 指定字段的初始值,默认为None。当给字段的initial属性设定一个非空值时,页面中的对应表单将使用这个值填充。
  • help_text
    • 用于给当前的字段添加描述性信息,提示当前字段的作用或需要输入的内容解释。如果设定了该属性,则其在页面中将会显示在旁边。
  • error_messages
    • 用于覆盖Field默认的错误消息。
    •  error_messages={'required': '错误信息'}

  • disabled
    • 其默认值是False,如果修改为True,则当前的表单字段将不可编辑。当设置字段为不可编辑时,需要提供初始值(initial),否则,这个字段也就没有意义了。

常用的表单字段类型

Django表单系统内置了数十种表单字段类型,几乎可以满足所有的表单使用场景。如果这些内置的字段类型都不能满足所需的业务场景,Django也支持自定义Field类。

  • CharField
    • 其为字符串类型的表单字段,是最常见的表单字段类型,widget默认使用TextInput
    • max_length限制字段值的最大长度
    • min_length限制字段值的最小长度
    • strip属性默认会执行Python字符串的strip方法,用于去除字符串开头和尾部的空格。如果不需要这样做,可以将strip属性设置为False:
    • empty_value:用来表示"空"的值。默认为空字符串。
  • IntegerField
    • 其为整数类型的表单字段,widget默认使用NumberInput。
    • 可选的max_value与min_value参数用于限定字段值的取值范围,且它们都是闭区间。如果提供了这两个参数(或其中之一),且给定的字段值不在取值范围内,将会抛出异常,并带有错误提示信息。
  • BooleanField
    • 其为布尔类型的表单字段,widget默认使用CheckboxInput。
    • 由于基类Field的required属性默认是True,所以,在不做设置的情况下,BooleanField实例的required属性也是True。由于required为True要求这个字段值必须提供,所以,这种情况下,BooleanField类型的实例必须是True,否则将抛出异常,并提示:“This fieldis required.”。
    • 如果要在表单中使用BooleanField字段,则需要指定required为False:
  • ChoiceField
    • 其为选择类型的表单字段,widget默认使用Select。
    • choices参数需要一个可迭代的二元组或能够返回可迭代二元组的函数对象。与模型中的choices参数使用方法一样。
  • EmailField
    • 它继承自CharField,但是提供了Email验证器,用于校验传递的字段值是否是合法的电子邮件地址。widget默认使用EmailInput。
    • 除了EmailField之外,表单系统还提供了UUIDField、GenericIPAddressField、URLField等基于CharField的字段类型用于校验特定结构的字符串。
  • UUIDField
    • 与EmailField类似,不过它只会验证数据是否会空,并会自动将数据生成唯一列,并设置为主键
  • JSONField
    • 一个接受 JSON 编码数据的字段,验证给定值是否为有效的 JSON。
  • GenericIPAddressField
    • 与EmailField类似,不过是验证给定的值是一个有效的 IP 地址。
  • URLField
    • 与EmailField类似,不过是验证给定值是一个有效的 URL的。
  • DateTimeField
    • 用于表示时间的表单字段,widget默认使用DateTimeInput。
    • 接受一个可选的参数input_formats,这个参数是一个列表,列表元素规定了可以转换为datetime.datetime的时间格式。
    •  DateTimeField的clean方法接受的值类型可以是datetime.datetime、datetime.date或符合特定格式的字符串,最终会返回datetime.datetime对象或抛出异常。

基于Model定制的表单

将Model翻译成表单是很常见的业务场景,利用Form对象并不难实现,只需要将Model中定义的字段翻译成Form对象中的表单字段即可。但是,如果这种需求很多,且Model中定义的字段也较多,那么重复实现这种表单的过程会很烦琐的。Django表单系统考虑到了这个问题,提供了ModelForm,可以基于Model的定义自动生成表单,很大程度上简化了Model翻译成表单的过程。译成表单字段类型,但是,并不会翻译所有的字段,editable=False的模型字段都不会出现在ModelForm中,如自增主键、自动添加的时间字段等。

ModelForm定义方式

class PrettyModelForm(forms.ModelForm):
    class Meta:
        model = models.PrettyNum
        fields = ["name", ]
        # fields = "__all__"
        # exclude = ['level']

 上面代码中就是自动生成了models.PrettyNum模型中的name字段的表单。

常用的Meta选项

  • fields
    • 其为列表或元组类型,
    • 它指定当前的表单应该包含哪些字段,如果要所有的Model字段都包含在表单中,可以设定fields='__all__'。
    • ModelForm的定义中必须要包含fields或exclude选项,否则将会抛出异常,同时给出错误提示:Creating a ModelForm without eitherthe'fields'attribute or the'exclude'attribute isprohibited。
  • exclude
    • 与fields类似,不过是指向当前的表单不应该包含哪些字段,是与fields相反
  • labels
    • 其为字典类型,用于定义表单字段的名称(输入框左边显示的名称)。表单字段的名称首先会使用Model字段定义设置的verbose_name,如果没有设置,则直接使用字段名。因此当没有定义verbose_name时,就可以使用labels选项来指定字段名。
  • help_texts
    • 其为字典类型,用于给表单字段添加帮助信息。目前页面中表单字段的帮助信息(输入框下方显示的内容)来自Model字段的help_texts定义,如果没有定义则什么都不显示。help_texts的定义方式与labels选项类似,
  • widgets
    • 其为字典类型,用于定义表单字段选用的控件。默认情况下,ModelForm会根据Model字段的类型映射表单Field类,因此会应用Field类中默认定义的widgets。这个选项用于自定义控件类型
  • field_classes
    • 其为字典类型,用于指定表单字段使用的Field类型。默认情况下,对于title字段,ModelForm会将它映射为fields.CharField类型。可以根据需要改变这种默认行为

表单中的常用方法

  • is_valid()
    • 校验字段值的合法性
  • cleaned_data属性
    • 获取清理后的字段值
  • save()
    • 字段值通过校验(is_valid)之后,可以使用ModelForm提供的save方法实现Model对象的保存。
  • instance
    • 添加表单数据,如果有些数据是不需要用户输入的,需要后台自动生成则使用该方法。
    • form.instance.字段名 = 值
  • errors
    • 包含了表单的错误信息,这是一个属性,是一个列表格式
  • label
    • 表示表单的名字,是一个属性,由模型中verbose_name属性控制。
  • add_error
    • 添加表单错误信息。
    • form.add_error('字段名', '详细信息')
    • 表示会在该字段名的错误消息里添加详细信息 

注意:使用ModelForm类时,需要先使用该类生成对象。如果需要获取使用ModelForm验证的数据则为:

form = PrettyModelForm(data=request.POST)

PrettyModelForm是类名

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Django表单系统 的相关文章

  • 替换字符串列表中的 \x00 的最佳方法?

    我有一个来自已解析 PE 文件的值列表 其中包括 x00每个部分末尾的空字节 我希望能够删除 x00字符串中的字节而不删除所有字节 x 文件中的 s 我试过做 replace and re sub 但并没有取得太大成功 使用Python 2
  • 如何在 Ubuntu 上安装 Python 模块

    我刚刚用Python写了一个函数 然后 我想将其做成模块并安装在我的 Ubuntu 11 04 上 这就是我所做的 创建 setup py 和 function py 文件 使用 Python2 7 setup py sdist 构建分发文
  • 用 Python 编写一个无操作或虚拟类

    假设我有这样的代码 foo fooFactory create 由于种种原因 fooFactory create 可能无法创建实例Foo 如果可以的话我想要fooFactory create 返回一个虚拟 无操作对象 这个对象应该是完全惰性
  • 获取单个方程的脚本

    在文本文件中输入 a 2 8 b 3 9 c 4 8 d 5 9 e a b f c d g 0 6 h 1 7 i e g j f h output i j 期望的输出 输出 2 8 3 9 0 6 4 8 5 9 1 7 如果输入文件名
  • Sorted(key=lambda: ...) 背后的语法[重复]

    这个问题在这里已经有答案了 我不太明白背后的语法sorted 争论 key lambda variable variable 0 Isn t lambda随意的 为什么是variable在看起来像的内容中陈述了两次dict 我认为这里的所有
  • 使用正则表达式解析 Snort 警报文件

    我正在尝试使用 Python 中的正则表达式从 snort 警报文件中解析出源 目标 IP 和端口 和时间戳 示例如下 03 09 14 10 43 323717 1 2008015 9 ET MALWARE User Agent Win9
  • Python:当前目录是否自动包含在路径中?

    Python 3 4 通过阅读其他一些 SO 问题 似乎如果moduleName py文件位于当前目录之外 如果要导入它 必须将其添加到路径中sys path insert 0 path to application app folder
  • 无法使用数据库路由器通过 save_model 进行保存

    我正在使用数据库路由器 因此我的应用程序有两个数据库 一个数据库用于默认 django 数据 另一个数据库用于存储默认 django 数据 在我的管理员中我已经覆盖了save model函数以保存created by变量 但我无法做到这一点
  • 将一个时间序列插入到 pandas 中的另一个时间序列中

    我有一组定期测量的值 说 import pandas as pd import numpy as np rng pd date range 2013 01 01 periods 12 freq H data pd Series np ran
  • 将 subprocess.Popen 的输出通过管道传输到文件

    我需要启动一些长时间运行的进程subprocess Popen 并希望拥有stdout and stderr从每个自动管道到单独的日志文件 每个进程将同时运行几分钟 我想要两个日志文件 stdout and stderr 每个进程当进程运行
  • VSCode pytest 测试发现失败

    Pytest 测试发现失败 用户界面指出 Test discovery error please check the configuration settings for the tests 输出窗口显示 Test Discovery fa
  • Python 中的这种赋值方式叫什么? a = b = 真

    我知道关于元组拆包 http docs python org tutorial datastructures html tuples and sequences但是当一行中有多个等号时 这个赋值被称为什么 阿拉a b True 它总是让我有
  • 在wxpython中使用wx.TextCtrl并在按钮单击后显示数据的简单示例 - wx新手

    我正在学习 python 并尝试使用 wxpython 进行 UI 开发 也没有 UI exp 我已经能够创建一个带有面板 按钮和文本输入框的框架 我希望能够在文本框中输入文本 并让程序在单击按钮后对输入框中的文本执行操作 我可以获得一些关
  • 字典的嵌套列表

    我正在尝试创建dict通过嵌套list groups Group1 A B Group2 C D L y x 0 for y in x if y x 0 for x in groups d k v for d in L for k v in
  • django 模板上的 vscode html 自动套用格式

    我喜欢 VSCode 的保存自动格式功能 直到它弄乱了我的模板代码 它错误地将我的 django 模板语法格式化为一行代码 有时非常长的一行 所以不用这段代码 for row in ABCDEFGH tr for col in 123456
  • Python int 太大,无法放入 SQLite

    我收到错误 OverflowError Python int 太大 无法转换为 SQLite INTEGER 来自以下代码块 该文件约25GB 因此必须分部分读取 length 6128765 Works on partitions of
  • 是否可以写一个负的python类型注释

    这可能听起来不合理 但现在我需要否定类型注释 我的意思是这样的 an int Not Iterable a string Iterable 这是因为我为一个函数编写了一个重载 而 mypy 不理解我 我的功能看起来像这样 overload
  • Google App Engine 中的自定义身份验证

    有谁知道或知道我可以在哪里学习如何使用 Python 和 Google App Engine 创建自定义身份验证流程 我不想使用 Google 帐户进行身份验证 并且希望能够创建自己的用户 如果不是专门针对 Google App Engin
  • 将 Scikit-Learn OneHotEncoder 与 Pandas DataFrame 结合使用

    我正在尝试使用 Scikit Learn 的 OneHotEncoder 将 Pandas DataFrame 中包含字符串的列替换为 one hot 编码的等效项 我的下面的代码不起作用 from sklearn preprocessin
  • 如何在SqlAlchemy中执行“左外连接”

    我需要执行这个查询 select field11 field12 from Table 1 t1 left outer join Table 2 t2 ON t2 tbl1 id t1 tbl1 id where t2 tbl2 id is

随机推荐

  • 区块链-区块链特点

    目录 https blog csdn net qq 40452317 article details 89646633 区块链 Blockchain 是一系列现有成熟技术的有机组合 它对账本进行分布式的有效记录 并且提供完善的脚本以支持不同
  • Qt 2D图形平面绘制

    Qt 2D图形平面绘制 一 图形视图框架 Graphics View Framework 二 实战 1 步骤 2 代码 三 参考 四 总结 一 图形视图框架 Graphics View Framework QGraphicsScene 场景
  • RocketMQ解析

    文章目录 1 单机版消息中心 2 分布式消息中心 2 1 问题与解决 2 1 1 消息丢失的问题 2 1 2 同步落盘怎么才能快 2 1 3 消息堆积的问题 2 1 4 定时消息的实现 2 1 5 顺序消息的实现 2 1 6 分布式消息的实
  • 软件测试进阶篇

    测试专栏 软件测试的基本概念 关于软件测试 作为一个测试人员 这些基础知识必不可少 关于测试用例 目录 一 按照测试对象来划分 1 界面 2 可靠性的测试 3 容错性 4 文档测试 5 兼容性测试 6 易用性测试 7 安装卸载测试 8 安全
  • Java string的基本用法

    Java string的基本用法 一 定义字符串与子串 定义 String e 空字符串 String E Hello 提取子串使用Substring方法 String E Hello String s E substring 0 4 s等
  • 《数字化转型》——企业持续有效增长的新引擎

    中国国民经济和社会发展第十四个五年规划和2035念远景目标纲要 明确指出 迎接数字时代 激活数据要素潜能 推动网络强国建设 加快建设数字经济 数字社会 数字政府 以数字化转型整体驱动生产方式 生活方式和治理方式变革 那么企业如何做 如何选型
  • Nginx通过/etc/init.d/nginx方式启动或停止服务

    Linux Nginx启动 停止 重启脚本 Nginx 启动 重启 停止脚本 第一步 先运行命令关闭nginx sudo kill cat usr local nginx logs nginx pid lt
  • Python时间序列预测大气二氧化碳浓度

    二氧化碳 CO2 和甲烷 CH4 等温室气体 GHG 会在大气中捕获热量 从而使我们的星球保持温暖 对生物物种友好 无论如何 燃烧化石燃料等人类活动会导致大量温室气体排放 从而过度提高地球的全球平均温度 因此 向可持续的全球经济转型势在必行
  • 极光笔记

    01 营销人 你是否饱受困扰 作为营销人的你 从996到007 每天从早忙到晚 但还是没办法把访客转化成客户 作为营销人的你 想通过APP通知 短信 邮件 公众号消息等方式 把所有能想到的营销方式 万箭齐发 结果却收效甚微 作为营销人的你
  • unity 设置animation不循环

    Unity中动画创建后 将会生成一个后缀名为 anim的文件 里面包含着动画内容 里面有一个属性 叫Loop Time 创建时它默认是勾选的 如果想去掉 可先找到你生成动画时创建的 anim文件 点击它 在右边Inspector栏里面找到L
  • MediaCodec、OpenGL、OpenSL/AudioTrack 实现一款简单的视频播放器

    概述 功能很简单 大致流程为 1 MediaCodec 解码视频文件得到 YUV PCM 数据 2 OpenGL 将 YUV 转为 RGB 并渲染到 Surface 上 3 OpenSL AudoTrack 获取 PCM 数据并播放 需要的
  • IDEA插件ASM Bytecode Outline

    IDEA插件ASM Bytecode Outline
  • Python之map()函数详解

    文章目录 一 map 函数简介 1 1 map 函数基本语法 1 2 map 函数 lambda表达式 1 3 map 函数输入多个可迭代对象iterable 1 4 查看返回的迭代器内容 二 map 函数示例 示例一 使用 map 函数操
  • CentOS 7.6镜像下载

    目前在国内使用最多的两个Linux发行版本一个是CentOS 另外一个是Ubuntu CentOS是一个可以重新分发的开源操作系统 也是企业Linux发行版的领头羊 官方目前发布的最新CentOS版本为CentOS 9 那么如何到下载旧版本
  • 一个数组有 N 个元素,求连续子数组的最大和。 例如:[-1,2,1],和最大的连续子数组为[2,1],其和为 3

    1 题目描述 一个数组有 N 个元素 求连续子数组的最大和 例如 1 2 1 和最大的连续子数组为 2 1 其和为 3 输入描述 输入为两行 第一行一个整数n 1 lt n lt 100000 表示一共有n个元素 第二行为n个数 即每个元素
  • 从利用Arthas排查线上Fastjson问题到Java动态字节码技术(中)

    上一篇文章 中通过对一次线上事故的复盘 引出了福报厂的Arthas 一个建立在Java动态字节码技术之上的Java诊断工具 关于Arthas的使用方式就不赘述了 查看官方文档可以很快上手 玩法也特别多 上一篇中也仅仅只介绍了一种使用场景 即
  • c++ 建立链表并实现合并

    创建两个链表并实现两个链表相加 include
  • 《大型网站技术架构》序

    推荐序一 1 传统企业应用于大型网站应用的区别 传统的企业应用系统主要面对的技术挑战是处理复杂凌乱 干变万化的所谓业务逻辑 而大型网站主要面对的技术挑战是处理超大量的用户访问和海量的数据处理 前者的挑战来自功能性需求 后者的挑战来自非功能性
  • 树-广度优先和深度优先搜索算法

    广度优先和深度优先搜索算法 本章主要讲述广度优先搜索算法BFS Breadth First Search 和深度优先算法DFS Depth First Search 广度优先 从起点开始由近及远进行广泛搜索 一般使用队列实现 深度优先 从起
  • Django表单系统

    目录 使用Form对象定义表单 Form对象的特性 表单字段的基类Field 常用的表单字段类型 基于Model定制的表单 ModelForm定义方式 表单中的常用方法 在Web站点中与后端服务进行交互 通常使用表单提交的方式 表单提交数据