Python-Django系列—部件

部件是 Django 对 HTML 输入元素的表示。部件处理 HTML 的渲染,以及从对应于部件的 GET/POST 字典中提取数据。

内置部件生成的 HTML 使用 HTML5 语法,目标是 <!DOCTYPE html>。例如,它使用布尔属性,如 checked 而不是 XHTML 风格的 checked='checked'

一、指定部件

每当你在表单中指定一个字段时,Django 会使用一个默认的部件来显示数据类型。要想知道哪个字段使用的是哪个部件,请看 内置 Field 类 的文档。

但是,如果你想为一个字段使用不同的部件,你可以在字段定义中使用 widget 参数。例如:

from django import formsclass CommentForm(forms.Form):name = forms.CharField()url = forms.URLField()comment = forms.CharField(widget=forms.Textarea)

这将指定一个带有注释的表单,该表单使用一个较大的 Textarea 部件,而不是默认的 TextInput 部件。

二、为部件设置参数

许多部件都有可选的额外参数;它们可以在字段上定义部件时进行设置。在下面的例子中, years 属性被设置为 SelectDateWidget:
 

from django import formsBIRTH_YEAR_CHOICES = ["1980", "1981", "1982"]
FAVORITE_COLORS_CHOICES = {"blue": "Blue","green": "Green","black": "Black",
}class SimpleForm(forms.Form):birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))favorite_colors = forms.MultipleChoiceField(required=False,widget=forms.CheckboxSelectMultiple,choices=FAVORITE_COLORS_CHOICES,)

三、继承自 Select 部件的部件

继承自 Select 部件的部件处理选择。它们向用户提供了一个可供选择的选项列表。不同的部件以不同的方式呈现这种选择;Select 部件本身使用 <select> HTML 列表表示,而 RadioSelect 使用单选按钮。

ChoiceField 字段默认使用 Select 小部件。小部件上显示的选项从 ChoiceField 继承,并且更改 ChoiceField.choices 将更新 Select.choices。例如:

>>> from django import forms
>>> CHOICES = {"1": "First", "2": "Second"}
>>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
>>> choice_field.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices = []
>>> choice_field.choices = [("1", "First and only")]
>>> choice_field.widget.choices
[('1', 'First and only')]

然而,提供 chips 属性的部件可以与非基于选择的字段一起使用——例如 CharField——但当选择是模型固有的,而不仅仅是表示部件时,建议使用 ChoiceField 为基础的字段。

四、自定义部件实例

当 Django 将一个部件渲染成 HTML 时,它只渲染了非常少的标记——Django 不会添加类名,或任何其他部件的特定属性。这意味着,例如,所有的 TextInput 部件在你的网页上看起来都是一样的。

有两种方法来定制部件: 每个部件实例 和 每个部件类。

1、样式化部件实例

如果你想让一个部件实例看起来与另一个不同,你需要在实例化部件对象并将其分配给表单字段时指定额外的属性(也许还需要在你的 CSS 文件中添加一些规则)。

例如,采取以下表单:

from django import formsclass CommentForm(forms.Form):name = forms.CharField()url = forms.URLField()comment = forms.CharField()

此表单将包括用于 name 和 comment 字段的 TextInput 小部件,以及用于 url 字段的 URLInput 小部件。每个都有默认的渲染 —— 没有 CSS 类,没有额外的属性:

>>> f = CommentForm(auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" required></div>

在真实的网页上,你可能想要自定义这些。你可能希望评论的输入元素更大,并且你可能希望 'name' 小部件具有一些特殊的 CSS 类。还可以指定 'type' 属性以使用不同的 HTML5 输入类型。为此,你可以在创建小部件时使用 Widget.attrs 参数:

class CommentForm(forms.Form):name = forms.CharField(widget=forms.TextInput(attrs={"class": "special"}))url = forms.URLField()comment = forms.CharField(widget=forms.TextInput(attrs={"size": "40"}))

你也可以在表单定义中修改一个部件:

class CommentForm(forms.Form):name = forms.CharField()url = forms.URLField()comment = forms.CharField()name.widget.attrs.update({"class": "special"})comment.widget.attrs.update(size="40")

或者如果该字段没有直接在表单上声明(比如模型表单字段),可以使用 Form.fields 属性:

class CommentForm(forms.ModelForm):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.fields["name"].widget.attrs.update({"class": "special"})self.fields["comment"].widget.attrs.update(size="40")

Django 会将额外的属性包含在渲染的输出中:

>>> f = CommentForm(auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" class="special" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" size="40" required></div>

2、样式化部件类

有了部件,就可以添加静态资源(css 和 javascript)并更深入地定制它们的外观和行为。

简而言之,你需要对部件进行子类化,并且 定义一个内部“Media”类 或者 创建一个"media"属性。

这些方法涉及到一些高级的 Python 编程,在 表单静态资源 主题指南中有详细描述。

五、基础部件类

基础部件类 Widget 和 MultiWidget 被所有的 内置部件 子类化,可以作为自定义部件的基础。

1、Widget

class Widget(attrs=None)[source]
这个抽象类不能被渲染,但提供了基本属性 attrs。 你也可以在自定义部件上实现或重写 render() 方法。

attrs

包含要在渲染的部件上设置的 HTML 属性的字典。

>>> from django import forms
>>> name = forms.TextInput(attrs={"size": 10, "title": "Your name"})
>>> name.render("name", "A name")
'<input title="Your name" type="text" name="name" value="A name" size="10">'

如果你将属性赋值为 True 或 False,它将被渲染为 HTML5 的布尔属性:

>>> name = forms.TextInput(attrs={"required": True})
>>> name.render("name", "A name")
'<input name="name" type="text" value="A name" required>'
>>>
>>> name = forms.TextInput(attrs={"required": False})
>>> name.render("name", "A name")
'<input name="name" type="text" value="A name">'

supports_microseconds

属性,默认为 True。如果设置为 False,则 datetime 和 time 值的微秒部分将被设置为 0。

format_value(value)[source]

清理并返回一个值,供部件模板使用。value 并不能保证是有效的输入,因此子类的实现应该是防御性的。

get_context(name, value, attrs)[source

返回渲染部件模板时要使用的值的字典。默认情况下,该字典包含一个键,'widget',它是一个包含以下键的部件的字典表示:

  • 'name':name 参数中的字段名称。
  • 'is_hidden':表示该部件是否被隐藏的布尔值。
  • 'required':表示该部件是否需要该字段的布尔值。
  • 'value':format_value() 返回的值。
  • 'attrs':拟在渲染的部件上设置的 HTML 属性。attrs 属性和 attrs 参数的组合。
  • ''template_name':self.template_name 的值。

Widget 子类可以通过覆盖该方法提供自定义上下文值。

id_for_label(id_)[source]
根据字段的 ID 返回此小部件的 HTML ID 属性,供 <label> 使用。如果没有可用的 ID,则返回空字符串。

这个钩子是必要的,因为一些部件有多个 HTML 元素,因此有多个 ID。在这种情况下,这个方法应该返回一个与部件标签中第一个 ID 对应的 ID 值。

render(name, value, attrs=None, renderer=None)[source]
使用给定的渲染器将部件渲染成 HTML。如果 renderer 为 None,则使用 FORM_RENDERER 设置中的渲染器。

value_from_datadict(data, files, name)[source]
给定一个数据字典和这个部件的名称,返回这个部件的值。files 可能包含来自 request.FILES 的数据。如果没有提供值,则返回 None。还需要注意的是,在处理表单数据的过程中,value_from_datadict 可能会被调用不止一次,所以如果你自定义它并添加昂贵的处理,你应该自己实现一些缓存机制。

value_omitted_from_data(data, files, name)[source]
给定 data 和 files 字典和这个部件的名称,返回该部件是否有数据或文件。

该方法的结果会影响模型表单中的字段 是否回到默认。

特殊情况有 CheckboxInput、CheckboxSelectMultiple 和 SelectMultiple,它们总是返回 False,因为未选中的复选框和未选择的 <select multiple>,不会出现在 HTML 表单提交的数据中,所以不知道用户是否提交了一个值。

use_fieldset
一个用于标识小部件在渲染时是否应该分组在一个带有 <legend> 的 <fieldset> 中的属性。默认为 False,但当小部件包含多个 <input> 标签时,例如 CheckboxSelectMultiple、RadioSelect、MultiWidget、SplitDateTimeWidget 和 SelectDateWidget 时,它为 True。

use_required_attribute(initial)[source]
给定一个表单字段的 initial 值,返回是否可以用 required HTML 属性来渲染部件。表单使用这个方法与 Field.required 和 Form.use_required_attribute 一起决定是否为每个字段显示 required 属性。

默认情况下,对隐藏的部件返回 False,否则返回 True。特殊情况是 FileInput 和 ClearableFileInput,当设置了 initial 时,返回 False;还有 CheckboxSelectMultiple,总是返回 False,因为浏览器验证需要选中所有的复选框,而不是至少一个。

在与浏览器验证不兼容的自定义部件中覆盖此方法。例如,一个由隐藏的 textarea 元素支持的 WSYSIWG 文本编辑部件可能希望总是返回 False 以避免浏览器对隐藏字段的验证。

2、MultiWidget

class MultiWidget(widgets, attrs=None)[source]
MultiWidget 与 MultiValueField 携手合作。

MultiWidget 有一个必要的参数:

widgets

一个包含所需小部件的可迭代对象。例如:

>>> from django.forms import MultiWidget, TextInput
>>> widget = MultiWidget(widgets=[TextInput, TextInput])
>>> widget.render("name", ["john", "paul"])
'<input type="text" name="name_0" value="john"><input type="text" name="name_1" value="paul">'

你可以提供一个字典来指定每个子小部件的 name 属性的自定义后缀。在这种情况下,对于每个 (key, widget) 对,将将 key 添加到小部件的 name 中以生成属性值。你可以为一个小部件提供空字符串(''),以取消一个小部件的后缀。例如:

>>> widget = MultiWidget(widgets={"": TextInput, "last": TextInput})
>>> widget.render("name", ["john", "paul"])
'<input type="text" name="name" value="john"><input type="text" name="name_last" value="paul">'

还有一个必要的方法:

decompress(value)[source]

这个方法从字段中获取一个“压缩”值,然后返回一个“解压缩”值的列表。可以假定输入值有效,但不一定是非空的。

这个方法 必须由子类实现,由于值可能是空的,所以实现必须是防御性的。

“解压”背后的原理是,需要将表单字段的组合值“拆分”成每个部件的值。

一个例子是 SplitDateTimeWidget 如何将一个 datetime 值变成一个列表,将日期和时间分成两个独立的值:

from django.forms import MultiWidgetclass SplitDateTimeWidget(MultiWidget):# ...def decompress(self, value):if value:return [value.date(), value.time()]return [None, None]

它提供了一些自定义上下文:

get_context(name, value, attrs)[source]
除了 Widget.get_context() 中描述的 'widget' 键之外,MultiWidget 还增加了一个 widget['subwidgets'] 键。

这些可以在部件模板中循环使用:

{% for subwidget in widget.subwidgets %}{% include subwidget.template_name with widget=subwidget %}
{% endfor %}


下面是一个例子,它子类为 MultiWidget,用于在不同的选择框中显示日期和年、月、日。这个部件的目的是与 DateField 而不是 MultiValueField 一起使用,因此我们实现了 value_from_datadict():

from datetime import date
from django import formsclass DateSelectorWidget(forms.MultiWidget):def __init__(self, attrs=None):days = {day: day for day in range(1, 32)}months = {month: month for month in range(1, 13)}years = {year: year for year in [2018, 2019, 2020]}widgets = [forms.Select(attrs=attrs, choices=days),forms.Select(attrs=attrs, choices=months),forms.Select(attrs=attrs, choices=years),]super().__init__(widgets, attrs)def decompress(self, value):if isinstance(value, date):return [value.day, value.month, value.year]elif isinstance(value, str):year, month, day = value.split("-")return [day, month, year]return [None, None, None]def value_from_datadict(self, data, files, name):day, month, year = super().value_from_datadict(data, files, name)# DateField expects a single string that it can parse into a date.return "{}-{}-{}".format(year, month, day)


构造函数在一个列表中创建了几个 Select 部件。super() 方法使用这个列表来建立部件。

所需的方法 decompress() 将一个 datetime.date 的值分解成对应于每个部件的日、月、年的值。如果选择了一个无效的日期,比如不存在的 2 月 30 日,那么 DateField 就会把这个方法传给一个字符串代替,所以需要进行解析。最后的 return 处理的是 value 是 None 的时候,也就是说我们的子部件没有任何默认值。

value_from_datadict() 的默认实现是返回一个与每个 Widget 对应的值列表。这在使用 MultiWidget 与 MultiValueField` 时是合适的。但由于我们想将这个部件与一个 DateField 一起使用,它只取一个值,我们已经覆盖了这个方法。这里的实现将来自子部件的数据组合成一个字符串,其格式为 DateField 所期望的格式。

 

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

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

相关文章

【Leetcode 每日一题】2799. 统计完全子数组的数目

问题背景 给你一个由 正 整数组成的数组 n u m s nums nums。 如果数组中的某个子数组满足下述条件&#xff0c;则称之为 完全子数组 &#xff1a; 子数组中 不同 元素的数目等于整个数组不同元素的数目。 返回数组中 完全子数组 的数目。 子数组 是数组中的一个连续非空序…

卷积神经网络(二)

1 卷积运算的两个问题&#xff1a; 1.1 图像边缘信息使用少 边缘的像素点可能只会被用一次或者2次&#xff0c;中间的会用的更多。 1.2 图像被压缩 5*5的图像&#xff0c;如果经过3*3的卷积核后&#xff0c;大小变成3*3的。 N*N的图像&#xff0c;果经过F*F的卷积核后&#x…

组网技术-DHCP服务器,RIP协议,OSPF协议

1.DHCP Server提供三种IP地址分配策略&#xff1a; 手工分配地址 自动分配地址 n 动态分配地址 2.DHCP报文类型 DHCP DISCOVER(广播)&#xff1a;用于寻址DHCP Server DHCP OFFER&#xff08;单播&#xff09;&#xff1a;携带分配给客户端的IP地址 DHCP REQUEST&#xff08;…

反爬策略应对指南:淘宝 API 商品数据采集的 IP 代理与请求伪装技术

一、引言​ 在电商数据驱动决策的时代&#xff0c;淘宝平台海量的商品数据极具价值。然而&#xff0c;淘宝为保障平台安全和用户体验&#xff0c;构建了严密的反爬体系。当采集淘宝 API 商品数据时&#xff0c;若不采取有效措施&#xff0c;频繁的请求极易触发反爬机制&#x…

学习笔记(算法学习+Maven)

单调队列优化多重背包 #include <bits/stdc.h> using namespace std; const int M 2010; const int N 20010; int q[N]; int hh 0, tt -1; int f[N]; int g[N]; int v[M], w[M], s[M]; int n, m; int main() { cin >> n >> m; for (int i 1; …

WPF之项目创建

文章目录 引言先决条件创建 WPF 项目步骤理解项目结构XAML 与 C# 代码隐藏第一个 "Hello, WPF!" 示例构建和运行应用程序总结相关学习资源 引言 Windows Presentation Foundation (WPF) 是 Microsoft 用于构建具有丰富用户界面的 Windows 桌面应用程序的现代框架。它…

JAVAEE初阶01

个人主页 JavaSE专栏 JAVAEE初阶01 操作系统 1.对下&#xff08;硬件&#xff09;管理各种计算机设备 2.对上&#xff08;软件&#xff09;为各种软件提供一个稳定的运行环境 线程 运行的程序在操作系统中以进程的形式存在 进程是系统分配资源的最小单位 进程与线程的关…

HTML快速入门-4:HTML <meta> 标签属性详解

<meta> 标签是 HTML 文档头部&#xff08;<head> 部分&#xff09;的重要元素&#xff0c;用于提供关于文档的元数据&#xff08;metadata&#xff09;。这些数据不会直接显示在页面上&#xff0c;但对浏览器、搜索引擎和其他服务非常重要。 常用属性 1. name 和 …

前端基础之《Vue(12)—插件封装》

一、插件封装 1、在Vue生态中&#xff0c;除了Vue本身&#xff0c;其它所有的与Vue相关的第三方包&#xff0c;都是插件 例子&#xff1a; import VueRouter form vue-router Vue.use(VueRouter) // 注册插件 2、如何封装Vue插件 &#xff08;1&#xff09;第一种写法 const…

TCP基础题:音乐播放列表管理系统

需求描述 服务器端 创建一个 TCP 服务器&#xff0c;监听本地的 9999 端口&#xff0c;支持多个客户端连接。维护一个音乐播放列表&#xff0c;每个音乐条目包含歌曲名称、歌手、时长等信息。能够处理客户端的以下请求&#xff1a; 添加音乐到播放列表&#xff1a;接收客户端发…

Verilog 语法 (二)

在掌握了 Verilog 的基础语法和常用程序框架之后&#xff0c;本节将带大家深入学习一些 高级设计知识点。这些内容包括&#xff1a; 阻塞赋值&#xff08;&#xff09;与非阻塞赋值&#xff08;<&#xff09;的区别及使用场景&#xff1b; assign 和 always 语句的差异&am…

OpenCV 图形API(61)图像特征检测------检测图像边缘的函数Canny()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 使用Canny算法在图像中查找边缘。 该函数在输入图像中查找边缘&#xff0c;并使用Canny算法在输出映射&#xff08;edges&#xff09;中标记它们…

ubantu中下载编译安装qt5.15.3

操作步骤如下&#xff1a; 克隆 Qt 仓库&#xff1a; git clone https://code.qt.io/qt/qt5.git cd qt5 切换到 Qt 5.15.3 标签&#xff1a; git checkout v5.15.3-lts-lgpl 初始化子模块&#xff1a; perl init-repository 配置和编译 Qt&#xff1a; ./configure -prefix $H…

毕业论文设计基本内容和要求:

毕业设计基本内容和要求&#xff1a; 研究内容 调查了解LAMP架构和PHP开发&#xff1b; 学习百度旅游调用的其他产品线服务并熟悉请求接口&#xff1b; 学习社区业务层规范&#xff1b; 设计并实现旅游主要模块&#xff1b; 技术指标 熟悉企业中流程运转的方式&#xff0c;…

【大语言模型】大语言模型(LLMs)在工业缺陷检测领域的应用

大语言模型&#xff08;LLMs&#xff09;在工业缺陷检测领域的应用场景正在快速扩展&#xff0c;结合其多模态理解、文本生成和逻辑推理能力&#xff0c;为传统检测方法提供了新的技术路径。以下是该领域的主要应用场景及相关技术进展&#xff1a; 1. 多模态缺陷检测与解释 视…

【AI插件开发】Notepad++ AI插件开发1.0发布和使用说明

一、产品简介 AiCoder是一款为Notepad设计的轻量级AI辅助插件&#xff0c;提供以下核心功能&#xff1a; 嵌入式提问&#xff1a;对选中的文本内容进行AI分析&#xff0c;通过侧边栏聊天界面与AI交互&#xff0c;实现多轮对话、问题解答或代码生成。对话式提问&#xff1a;独…

第2讲:R语言中的色彩美学——科研图表配色指南

目录 一、背景导引:科研图表为何需要“配色讲究”? 二、色彩基础认知:别让“红绿盲”错过你的科研成果 三、R语言中的配色库全景图 四、案例演示与代码实战 🎨案例1:ggplot2 + viridis 配色的热图 🎨案例2:MetBrewer 中的印象派色彩 五、技巧点拨:如何为SCI图…

基于Django的个性化股票交易管理系统

本项目基于Python3.6、Django2.1、MySql8.0&#xff08;最好不要使用5.6&#xff0c;字符集等方面均不兼容&#xff0c;否则导入数据库会出错&#xff09;与股票信息工具包TuShare实现。 创建或激活对应Python开发环境 这里使用了conda来管理环境&#xff0c;强烈推荐&#xf…

超越GPT-4?下一代大模型的技术突破与挑战

超越GPT-4&#xff1f;下一代大模型的技术突破与挑战 引言&#xff1a;大模型的演进历程 人工智能领域近年来最引人注目的发展莫过于大型语言模型(Large Language Models, LLMs)的快速进步。从GPT-3到GPT-4&#xff0c;再到如今各种宣称"超越GPT-4"的模型不断涌现&…

Js 之点击下拉搜索Ajax-Bootstrap-Select

一、效果图 二、文档 https://gitcode.com/gh_mirrors/aj/Ajax-Bootstrap-Select/tree/master 三、示例代码 引入插件js、css <link rel"stylesheet" href"{php echo MODULE_URL}template/lib/bootstrap-select/css/bootstrap-select.min.css"> <…