---恢復內容開始---javascript
Rendering an attractive and easy-to-use Web form requires more than just HTML - it also requires CSS stylesheets, and if you want to use fancy 「Web2.0」 widgets, you may also need to include some JavaScript on each page. The exact combination of CSS and JavaScript that is required for any given page will depend upon the widgets that are in use on that page.css
★渲染form須要組合HTML,CSS和JavaScript。java
This is where Django media definitions come in. Django allows you to associate different media files with the forms and widgets that require that media. For example, if you want to use a calendar to render DateFields, you can define a custom Calendar widget. This widget can then be associated with the CSS and JavaScript that is required to render the calendar. When the Calendar widget is used on a form, Django is able to identify the CSS and JavaScript files that are required, and provide the list of file names in a form suitable for easy inclusion on your Web page.python
★Django media 是寫在 Widgets 裏的,用來作 widget 被應用到 form 時的渲染工做(CSS和JavaScript)。web
Media and Django Admindjango
The Django Admin application defines a number of customized widgets for calendars, filtered selections, and so on. These widgets define media requirements, and the Django Admin uses the custom widgets in place of the Django defaults. The Admin templates will only include those media files that are required to render the widgets on any given page.app
If you like the widgets that the Django Admin application uses, feel free to use them in your own application! They’re all stored in django.contrib.admin.widgets.less
★django.contrib.admin.widgets定義了一系列的widgets。ide
Which JavaScript toolkit?ui
Many JavaScript toolkits exist, and many of them include widgets (such as calendar widgets) that can be used to enhance your application. Django has deliberately avoided blessing any one JavaScript toolkit. Each toolkit has its own relative strengths and weaknesses - use whichever toolkit suits your requirements. Django is able to integrate with any JavaScript toolkit.
★Django 能夠使用任何的JavaScript toolkit。
The easiest way to define media is as a static definition. Using this method, the media declaration is an inner class. The properties of the inner class define the media requirements.
Here’s a simple example:
class CalendarWidget(forms.TextInput): class Media: css = { 'all': ('pretty.css',) } js = ('animations.js', 'actions.js')
★在內部類Media定義css和js ,這時定義的是靜態的media。
This code defines a CalendarWidget, which will be based on TextInput. Every time the CalendarWidget is used on a form, that form will be directed to include the CSS file pretty.css, and the JavaScript filesanimations.js and actions.js.
★當這個定製的widget被應用到 form 上時,此form就會被導入CSS文件pretty.css 和 JavaScript 文件 animations.js 和 actions.js
This static media definition is converted at runtime into a widget property named media. The media for a CalendarWidget instance can be retrieved through this property:
>>> 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>
Here’s a list of all possible Media options. There are no required options.
A dictionary describing the CSS files required for various forms of output media.
The values in the dictionary should be a tuple/list of file names. See the section on media paths for details of how to specify paths to media files.
The keys in the dictionary are the output media types. These are the same types accepted by CSS files in media declarations: ‘all’, ‘aural’, ‘braille’, ‘embossed’, ‘handheld’, ‘print’, ‘projection’, ‘screen’, ‘tty’ and ‘tv’. If you need to have different stylesheets for different media types, provide a list of CSS files for each output medium. The following example would provide two CSS options – one for the screen, and one for print:
class Media: css = { 'screen': ('pretty.css',), 'print': ('newspaper.css',) }
If a group of CSS files are appropriate for multiple output media types, the dictionary key can be a comma separated list of output media types. In the following example, TV’s and projectors will have the same media requirements:
class Media: css = { 'screen': ('pretty.css',), 'tv,projector': ('lo_res.css',), 'print': ('newspaper.css',) }
★當key包含多個值時,用逗號分隔。
If this last CSS definition were to be rendered, it would become the following 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" />
A tuple describing the required JavaScript files. See the section on media paths for details of how to specify paths to media files.
A boolean defining inheritance behavior for media declarations.
By default, any object using a static media definition will inherit all the media associated with the parent widget. This occurs regardless of how the parent defines its media requirements. For example, if we were to extend our basic Calendar widget from the example above:
>>> 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>
★默認的狀況下,若存在繼承關係,widget會繼承父類的 media
The FancyCalendar widget inherits all the media from it’s parent widget. If you don’t want media to be inherited in this way, add an extend=False declaration to the media declaration:
>>> 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,用 extend = False
If you require even more control over media inheritance, define your media using a dynamic property. Dynamic properties give you complete control over which media files are inherited, and which are not.
★若想部分繼承,參考上面的鏈接
If you need to perform some more sophisticated manipulation of media requirements, you can define the media property directly. This is done by defining a widget property that returns an instance offorms.Media. The constructor for forms.Media accepts css and js keyword arguments in the same format as that used in a static media definition.
★想表現更復雜的操做,能夠經過動態的定義 media 實現。能夠直接定義 media 屬性。只須要在定製的widget類裏返回一個 forms.Media 的實例。
Media 接收的也是 css 和 js 參數。
For example, the static media definition for our Calendar Widget could also be defined in a dynamic fashion:
class CalendarWidget(forms.TextInput): def _media(self): return forms.Media(css={'all': ('pretty.css',)}, js=('animations.js', 'actions.js')) media = property(_media)
★這是動態定義media的例子。
See the section on Media objects for more details on how to construct return values for dynamic media properties.
★如何詳細構建動態的media看上面的連接。
Paths used to specify media can be either relative or absolute. If a path starts with /, http:// or https://, it will be interpreted as an absolute path, and left as-is. All other paths will be prepended with the value of the appropriate prefix.
★media中的path能夠是相對路徑也能夠是絕對路徑。若是path以/, http:// 或 https://開頭,那麼path就是絕對路徑。
As part of the introduction of the staticfiles app two new settings were added to refer to 「static files」 (images, CSS, Javascript, etc.) that are needed to render a complete web page: STATIC_URL andSTATIC_ROOT.
★額外的staticfiles app被加入。
To find the appropriate prefix to use, Django will check if the STATIC_URL setting is not None and automatically fall back to using MEDIA_URL. For example, if the MEDIA_URL for your site was'http://uploads.example.com/' and STATIC_URL was None:
>>> 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>
But if STATIC_URL is '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>
★Django會先查找 STATIC_URL ,若爲空則去查找 MEDIA_URL。
When you interrogate the media attribute of a widget or form, the value that is returned is a forms.Mediaobject. As we have already seen, the string representation of a Media object is the HTML required to include media in the <head> block of your HTML page.
However, Media objects have some other interesting properties.
If you only want media of a particular type, you can use the subscript operator to filter out a medium of interest. For example:
>>> 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" />
When you use the subscript operator, the value that is returned is a new Media object – but one that only contains the media of interest.
★能夠選擇部分的media,用subscript操做符過濾出感興趣的media。 其返回值也是 Media 對象。
Media objects can also be added together. When two media objects are added, the resulting Media object contains the union of the media from both files:
>>> 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的組合
Widgets aren’t the only objects that can have media definitions – forms can also define media. The rules for media definitions on forms are the same as the rules for widgets: declarations can be static or dynamic; path and inheritance rules for those declarations are exactly the same.
★不僅在widget裏能定義media,在form裏可能夠定義media。在form裏定義media的規則和在widget裏同樣。
Regardless of whether you define a media declaration, all Form objects have a media property. The default value for this property is the result of adding the media definitions for all widgets that are part of the form:
>>> 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>
★不管是否認義了一個media,forms自帶media屬性。
If you want to associate additional media with a form – for example, CSS for form layout – simply add a media declaration to the form:
★若是你想在form裏添加一個額外的form,只需在form裏聲明一個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>