django1.8官方文件翻譯:5-2-2表單素材(Media類)
表單素材 ( Media
類)
渲染有吸引力的、易於使用的web表單不僅僅需要HTML – 同時也需要CSS樣式表,並且,如果你打算使用奇妙的web2.0元件,你也需要在每個頁面包含一些JavaScript。任何提供的頁面都需要CSS和JavaScript的精確配合,它依賴於頁面上所使用的元件。
這就是素材定義所匯入的位置。Django允許你將一些不同的檔案 – 像樣式表和指令碼 – 與需要這些素材的表單和元件相關聯。例如,如果你想要使用日曆來渲染DateField,你可以定義一個自定義的日曆元件。這個元件可以與渲染日曆所需的CSS和JavaScript關聯。當日歷元件用在表單上的時候,Django可以識別出所需的CSS和JavaScript檔案,並且提供一個檔名的列表,以便在你的web頁面上簡單地包含這些檔案。
素材和Django Admin
Django的Admin應用為日曆、過濾選擇等一些東西定義了一些自定義的元件。這些元件定義了素材的需求,DJango Admin使用這些自定義元件來代替Django預設的元件。Admin模板只包含在提供頁面上渲染元件所需的那些檔案。
如果你喜歡Django Admin應用所使用的那些元件,可以在你的應用中隨意使用它們。它們位於django.contrib.admin.widgets
。
選擇哪個JavaScript工具包?
現在有許多JavaScript工具包,它們中許多都包含元件(比如日曆元件),可以用於提升你的應用。Django 有意避免去稱讚任何一個JavaScript工具包。每個工具包都有自己的有點和缺點 – 要使用適合你需求的任何一個。Django 有能力整合任何JavaScript工具包。
作為靜態定義的素材
定義素材的最簡單方式是作為靜態定義。如果使用這種方式,定義在Media
內部類中出現,內部類的屬性定義了需求。
這是一個簡單的例子:
from django import forms
class CalendarWidget(forms.TextInput):
class Media:
css = {
`all`: (`pretty.css`,)
}
js = (`animations.js`, `actions.js`)
上面的程式碼定義了 CalendarWidget
,它繼承於TextInput
。每次CalendarWidget在表單上使用時,表單都會包含CSS檔案pretty.css
,以及JavaScript檔案animations.js
和 actions.js
。
靜態定義在執行時被轉換為名為media
的元件屬性。CalendarWidget
例項的素材列表可以通過這種方式獲取:
>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
下面是所有可能的Media
選項的列表。它們之中沒有必需選項。
css
各種表單和輸出媒體所需的,描述CSS的字典。
字典中的值應該為檔名稱的列表或者元組。對於如何指定這些檔案的路徑,詳見路徑的章節。
字典中的鍵位輸出媒體的型別。它們和媒體宣告中CSS檔案接受的型別相同: ‘all’, ‘aural’, ‘braille’, ‘embossed’, ‘handheld’, ‘print’, ‘projection’, ‘screen’, ‘tty’ 和‘tv’。如果你需要為不同的媒體型別使用不同的樣式表,要為每個輸出媒體提供一個CSS檔案的列表。下面的例子提供了兩個CSS選項 – 一個用於螢幕,另一個用於列印:
class Media:
css = {
`screen`: (`pretty.css`,),
`print`: (`newspaper.css`,)
}
如果一組CSS檔案適用於多種輸出媒體的型別,字典的鍵可以為輸出媒體型別的逗號分隔的列表。在下面的例子中,TV和投影儀具有相同的媒體需求:
class Media:
css = {
`screen`: (`pretty.css`,),
`tv,projector`: (`lo_res.css`,),
`print`: (`newspaper.css`,)
}
如果最後的CSS定義即將被渲染,會變成下面的HTML:
<link href="http://static.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet" />
<link href="http://static.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet" />
<link href="http://static.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet" />
js
所需的JavaScript檔案由一個元組來描述。如何制定這些檔案的路徑,詳見路徑一節。
extend
一直布林值,定義了Media
宣告的繼承行為。
通常,任何使用靜態Media
定義的物件都會繼承所有和父元件相關的素材。無論父物件如何定義它自己的需求,都是這樣。例如,如果我們打算從上面的例子中擴充套件我們的基礎日曆控制元件:
>>> class FancyCalendarWidget(CalendarWidget):
... class Media:
... css = {
... `all`: (`fancy.css`,)
... }
... js = (`whizbang.js`,)
>>> w = FancyCalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<link href="http://static.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
FancyCalendar 元件繼承了所有父元件的素材。如果你不想讓Media
以這種方式被繼承,要向Media
宣告中新增 extend=False
宣告:
>>> class FancyCalendarWidget(CalendarWidget):
... class Media:
... extend = False
... css = {
... `all`: (`fancy.css`,)
... }
... js = (`whizbang.js`,)
>>> w = FancyCalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
如果你需要對繼承進行更多控制,要使用動態屬性來定義你的素材。動態屬性可以提供更多的控制,來控制繼承哪個檔案。
Media as a dynamic property
如果你需要對素材需求進行更多的複雜操作,你可以直接定義media
屬性。這可以通過定義一個返回forms.Media
例項的元件屬性來實現。forms.Media
的構造器接受 css
和 js
關鍵字引數,和在靜態媒體定義中的格式相同。
例如,我們的日曆元件的靜態定義可以定義成動態形式:
class CalendarWidget(forms.TextInput):
def _media(self):
return forms.Media(css={`all`: (`pretty.css`,)},
js=(`animations.js`, `actions.js`))
media = property(_media)
對於如何構建動態media
屬性的的返回值,詳見媒體物件一節。
素材定義中的路徑
用於指定素材的路徑可以是相對的或者絕對的。如果路徑以 /
,http://
或者https://
開頭,會被解釋為絕對路徑。所有其它的路徑會在開頭追加合適字首的值。
作為 staticfiles app的簡介的一部分,新增了兩個新的設定,它們涉及到渲染完整頁面所需的“靜態檔案”:STATIC_URL
和STATIC_ROOT
。
Django 會檢查是否STATIC_URL
設定不是None
,來尋找合適的字首來使用,並且會自動回退使用MEDIA_URL
。例如,如果你站點的 MEDIA_URL
是 `http://uploads.example.com/`
並且 STATIC_URL
是None
:
>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
... class Media:
... css = {
... `all`: (`/css/pretty.css`,),
... }
... js = (`animations.js`, `http://othersite.com/actions.js`)
>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://uploads.example.com/animations.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>
但如果STATIC_URL
為 `http://static.example.com/`
:
>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://othersite.com/actions.js"></script>
Media
物件
當你訪問表單上的一個元件的media
屬性時,返回值是一個forms.Media
物件。就像已經看到的那樣,表示 Media
物件的字串,是在你的HTML頁面的<head>
程式碼段包含相關檔案所需的HTML。
然而,Media
物件具有一些其它的有趣屬性。
素材的子集
如果你僅僅想得到特定型別的檔案,你可以使用下標運算子來過濾出你感興趣的媒體。例如:
>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
>>> print(w.media[`css`])
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
當你使用下標運算子的時候,返回值是一個新的 Media
物件,但是隻含有感興趣的媒體。
組合Media
物件
Media
物件可以新增到一起。新增兩個Media
的時候,產生的Media
物件含有二者指定的素材的並集:
>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
... class Media:
... css = {
... `all`: (`pretty.css`,)
... }
... js = (`animations.js`, `actions.js`)
>>> class OtherWidget(forms.TextInput):
... class Media:
... js = (`whizbang.js`,)
>>> w1 = CalendarWidget()
>>> w2 = OtherWidget()
>>> print(w1.media + w2.media)
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
表單上的Media
元件並不是唯一擁有media
定義的物件 – 表單可以定義media
。在表單上定義media
的規則和元件上面一樣:定義可以為靜態的或者動態的。宣告的路徑和繼承規則也嚴格一致。
無論是否你定義了media
, 所有表單物件都有media
屬性。這個屬性的預設值是,向所有屬於這個表單的元件新增media
定義的結果。
>>> from django import forms
>>> class ContactForm(forms.Form):
... date = DateField(widget=CalendarWidget)
... name = CharField(max_length=40, widget=OtherWidget)
>>> f = ContactForm()
>>> f.media
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
如果你打算向表單關聯一些額外的素材 – 例如,表單佈局的CSS – 只是向表單新增Media
宣告就可以了:
>>> class ContactForm(forms.Form):
... date = DateField(widget=CalendarWidget)
... name = CharField(max_length=40, widget=OtherWidget)
...
... class Media:
... css = {
... `all`: (`layout.css`,)
... }
>>> f = ContactForm()
>>> f.media
<link href="http://static.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
<link href="http://static.example.com/layout.css" type="text/css" media="all" rel="stylesheet" />
<script type="text/javascript" src="http://static.example.com/animations.js"></script>
<script type="text/javascript" src="http://static.example.com/actions.js"></script>
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
譯者:Django 文件協作翻譯小組,原文:Integrating media。
本文以 CC BY-NC-SA 3.0 協議釋出,轉載請保留作者署名和文章出處。
Django 文件協作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
相關文章
- Moya官方文件翻譯
- docker官方文件翻譯3Docker
- docker官方文件翻譯5Docker
- docker官方文件翻譯2Docker
- docker官方文件翻譯1Docker
- rabbitmq 官方文件翻譯-2MQ
- docker官方文件翻譯4Docker
- HTTPie 官方文件中文翻譯版HTTP
- BBNorm官方指導文件翻譯ORM
- [譯]記一次Kotlin官方文件翻譯的PR(內聯類)Kotlin
- jepsen 官方文件的中文翻譯版本
- Retrofit 2 0非常簡單的入門(翻譯官方文件)
- kotlinx協程官方文件中文翻譯版本Kotlin
- ExoPlayer的使用與解析(官方文件翻譯)
- voltDB官方文件第三章翻譯
- PendingIntent 是個啥?官方文件描述的很到位。我給翻譯翻譯Intent
- logback官方文件中文翻譯第七章:FiltersFilter
- 歡迎參與 KubeVela 官方文件翻譯活動
- TypeScript 官方手冊翻譯計劃【十二】:類TypeScript
- Detectron2-寫模型(Write Models)官方文件中文翻譯模型
- oc-plugin-book 文件協作翻譯外掛(類似 LearnKu.com 的文件翻譯)Plugin
- 文件翻譯器怎麼用?如何翻譯Word文件?
- RxJava常用操作符官方文件翻譯及Kotlin示例(1)RxJavaKotlin
- 別開心太早,Python 官方文件的翻譯差遠了Python
- Dapr 官方文件中文翻譯 v1.5 版本正式釋出
- ZooKeeper 官方教程[翻譯]
- [翻譯]CMAKE官方教程
- MPAndroidChart文件翻譯Android
- 前端工程基礎知識點--Browserslist (基於官方文件翻譯)前端
- 官方翻譯 | 有關基於文件的iOS應用開發iOS
- 前端工程基礎知識點–Browserslist (基於官方文件翻譯)前端
- 有ppt文件翻譯軟體嗎?如何翻譯整篇ppt文件
- 實用的Word文件翻譯方法分享,讓Word文件快速翻譯
- 怎麼翻譯整篇Excel文件?Excel文件翻譯一招搞定Excel
- [譯] AsyncDisplayKit/Texture 官方文件(2)
- [譯] AsyncDisplayKit/Texture 官方文件(1)
- 怎麼把Excel文件翻譯成中文?Excel文件翻譯方法介紹Excel
- Flutter-Cookbook 非官方翻譯Flutter
- influxdb官網文件翻譯UX