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.pswp.cn/bicheng/78578.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/78578.shtml
英文地址,請注明出處:http://en.pswp.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"> <…