当前位置: 首页 > news >正文

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">'

相关文章:

  • 国产DTU!工业DTU“性能翻倍+功耗减半”双突破!
  • 你学会了些什么211201?--http基础知识
  • Tez原理
  • OpenCV 图形API(44)颜色空间转换-----将图像从 BGR 色彩空间转换为 RGB 色彩空间函数BGR2RGB()
  • C++23 让 Lambda 表达式中的 () 更可选:P1102R2 提案深度解析
  • 在Ubuntu上查看PCL(Point Cloud Library)的版本
  • NLP高频面试题(四十九)大模型RAG常见面试题解析
  • SystemVerilog语法之定宽数组
  • 年化112.5%,最大回撤24.3%,卡玛比率4.62 | polars因子引擎重构完成(python源代码下载)
  • 智驱未来:AI大模型重构数据治理新范式
  • 声学重构+交互创新,特伦斯便携钢琴V30Pro专业演奏的移动化时代
  • [预备知识]2. PyTorch基本操作
  • MCP 框架中,stdio 模式和 SSE(Server-Sent Events) 模式的区别是什么
  • Pytorch的极简transformer用于时间序列预测
  • 【技术派后端篇】技术派中基于 Redis 的缓存实践
  • 分类算法中one-vs-rest策略和one-vs-one 策略的区别是什么?
  • 1.2软考系统架构设计师:系统架构的定义与作用 - 练习题附答案及超详细解析
  • C#+Visual Studio 2022为AutoCAD 2022开发插件并显示在Ribbon选项卡
  • [原理分析]安卓15系统大升级:Doze打盹模式提速50%,续航大幅增强,省电提升率5%
  • 单片机可以用来做机器人吗?
  • 全球在役最大火电厂被通报
  • 徐之凯评《突如其来的勇气》|早熟的抵抗
  • 深一度|上海半马,展示“体育+”无限可能的路跑狂欢
  • 特朗普就防卫负担施压日本,石破茂:防卫费应由我们自主决定
  • 圆桌|并购重组迎政策红利期,并购基金如何把握发展机遇?
  • 解放日报头版:再出发再创业,浦东以开放拥抱世界