---
title: "フォームアセット (Media クラス)"
version: 4.2
locale: ja
source: https://docs.djangoproject.com/ja/4.2/topics/forms/media/
canonical: https://djangodocs.dev/ja/4.2/topics/forms/media/
---
# フォームアセット (`Media` クラス)

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 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.

This is where asset definitions come in. Django allows you to
associate different files -- like stylesheets and scripts -- with the
forms and widgets that require those assets. 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 inclusion on your web page.

> **アセットと Django Admin**
>
> The Django Admin application defines a number of customized
> widgets for calendars, filtered selections, and so on. These
> widgets define asset requirements, and the Django Admin uses the
> custom widgets in place of the Django defaults. The Admin
> templates will only include those files that are required to
> render the widgets on any given page.
>
> 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`.

> **Which JavaScript toolkit?**
>
> 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.

## 定数として定義されたアセット

アセットを定義する最も簡単な方法は、定数とすることです。この方法を利用するには、内部 `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` を読み込めるようになります。

This static definition is converted at runtime into a widget property
named `media`. The list of assets for a `CalendarWidget` instance
can be retrieved through this property:

```pycon
>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>
```

以下は指定可能な `Media` オプションです。必須のものはありません。

### `css`

様々な形式の出力メディアに対して、必要な CSSファイルを定義するディクショナリです。

ディクショナリの値はファイル名のタプルかリストで指定します。ファイルのパスを指定する方法は [パスの章](#form-asset-paths) を参照してください。

ディクショナリのキーは、出力するメディアタイプを表します。これらは CSS ファイル認識可能なメディアタイプと同じです: 'all'、'aural'、'braille'、'embossed'、'handheld'、'print'、'projection'、'screen'、'tty'、'tv'。メディアタイプに応じたスタイルシートを提供する必要がある場合、各出力メディアに対して CSS ファイルを作成してください。以下の例は 2 つの CSS オプションを提供します -- 1 つはスクリーン用でもう一つは印刷用です:

```
class Media:
    css = {
        "screen": ["pretty.css"],
        "print": ["newspaper.css"],
    }
```

1 つのCSS ファイルのグループを複数の出力メディアタイプに適用するには、出力メディアタイプをカンマで区切ってディス書なりのキーに指定します。以下の例では、TV とプロジェクターは同じメディアを参照します:

```
class Media:
    css = {
        "screen": ["pretty.css"],
        "tv,projector": ["lo_res.css"],
        "print": ["newspaper.css"],
    }
```

If this last CSS definition were to be rendered, it would become the following HTML:

```html+django
<link href="http://static.example.com/pretty.css" media="screen" rel="stylesheet">
<link href="http://static.example.com/lo_res.css" media="tv,projector" rel="stylesheet">
<link href="http://static.example.com/newspaper.css" media="print" rel="stylesheet">
```

> **Changed in Django 4.1**
>
> In older versions, the `type="text/css"` attribute is included in CSS
> links.

### `js`

必要な JavaScript ファイルを定義したタプルです。ファイルのパスを指定する方法は [パスの章](#form-asset-paths) を参照してください。

### `extend`

`Media` 宣言に対する継承動作を定義する真偽値です。

By default, any object using a static `Media` definition will
inherit all the assets associated with the parent widget. This occurs
regardless of how the parent defines its own requirements. For
example, if we were to extend our basic Calendar widget from the
example above:

```pycon
>>> 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" media="all" rel="stylesheet">
<link href="http://static.example.com/fancy.css" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>
<script src="http://static.example.com/whizbang.js"></script>
```

The FancyCalendar widget inherits all the assets from its parent
widget. If you don't want `Media` to be inherited in this way, add
an `extend=False` declaration to the `Media` declaration:

```pycon
>>> 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" media="all" rel="stylesheet">
<script src="http://static.example.com/whizbang.js"></script>
```

継承をより詳細にコントロールするにあｈ、[動的なプロパティ](#dynamic-property) を使ってアセットを定義してください。 動的なプロパティを使えば、どのファイルを継承し、また継承しないかを完全にコントロールできます。

## 動的プロパティとしての `Media`

アセット要件のより詳細な操作が必要な場合、`media` プロパティを直接定義することができます。これは、`forms.Media` のインスタンスを返すウィジェットプロパティを定義することで実現できます。`forms.Media` に対するコンストラクタは、定数によるメディア定義と同様の形式で、`css` と `js` のキーワード引数を認識します。

例えば、上記例で扱ってきた Calendar Widget に対する定数の定義は、動的な方法では以下のように定義できます:

```
class CalendarWidget(forms.TextInput):
    @property
    def media(self):
        return forms.Media(
            css={"all": ["pretty.css"]}, js=["animations.js", "actions.js"]
        )
```

動的な `media` プロパティに対する戻り値を構成する方法については、Media objects\`\_ を参照してください。

## アセット定義内のパス

### Paths as strings

String paths used to specify assets 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. If the
[`django.contrib.staticfiles`](/ja/4.2/ref/contrib/staticfiles/#module-django.contrib.staticfiles) app is installed, it will be used to serve
assets.

mod:django.contrib.staticfiles を使うかどうかに関わらず、ウェブページを完全に表示するために [`STATIC_URL`](/ja/4.2/ref/settings/#std-setting-STATIC_URL) と [`STATIC_ROOT`](/ja/4.2/ref/settings/#std-setting-STATIC_ROOT) の設定が必要となります。

To find the appropriate prefix to use, Django will check if the
[`STATIC_URL`](/ja/4.2/ref/settings/#std-setting-STATIC_URL) setting is not `None` and automatically fall back
to using [`MEDIA_URL`](/ja/4.2/ref/settings/#std-setting-MEDIA_URL). For example, if the [`MEDIA_URL`](/ja/4.2/ref/settings/#std-setting-MEDIA_URL) for
your site was `'http://uploads.example.com/'` and [`STATIC_URL`](/ja/4.2/ref/settings/#std-setting-STATIC_URL)
was `None`:

```pycon
>>> 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" media="all" rel="stylesheet">
<script src="http://uploads.example.com/animations.js"></script>
<script src="http://othersite.com/actions.js"></script>
```

But if [`STATIC_URL`](/ja/4.2/ref/settings/#std-setting-STATIC_URL) is `'http://static.example.com/'`:

```pycon
>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://othersite.com/actions.js"></script>
```

Or if [`staticfiles`](/ja/4.2/ref/contrib/staticfiles/#module-django.contrib.staticfiles) is configured using the
[`ManifestStaticFilesStorage`](/ja/4.2/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage):

```pycon
>>> w = CalendarWidget()
>>> print(w.media)
<link href="/css/pretty.css" media="all" rel="stylesheet">
<script src="https://static.example.com/animations.27e20196a850.js"></script>
<script src="http://othersite.com/actions.js"></script>
```

### Paths as objects

> **New in Django 4.1**

Asset paths may also be given as hashable objects implementing an
`__html__()` method. The `__html__()` method is typically added using the
[`html_safe()`](/ja/4.2/ref/utils/#django.utils.html.html_safe) decorator. The object is responsible for
outputting the complete HTML `<script>` or `<link>` tag content:

```pycon
>>> from django import forms
>>> from django.utils.html import html_safe
>>>
>>> @html_safe
... class JSPath:
...     def __str__(self):
...         return '<script src="https://example.org/asset.js" rel="stylesheet">'
...

>>> class SomeWidget(forms.TextInput):
...     class Media:
...         js = [JSPath()]
...
```

## `Media` objects

ウィジェットやフォームの `media` 属性に応答指令信号を送ると、`forms.Media` オブジェクトが戻り値となります。すでに見たように、`Media` オブジェクトの文字列表現は HTMLで、HTML ページ内の `<head>` ブロックに関連ファイルを含める必要があります。

ただし、`Media` オブジェクトにはいくつかの面白いプロパティが存在します。

### アセットのサブセット

If you only want files of a particular type, you can use the subscript
operator to filter out a medium of interest. For example:

```pycon
>>> w = CalendarWidget()
>>> print(w.media)
<link href="http://static.example.com/pretty.css" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>

>>> print(w.media["css"])
<link href="http://static.example.com/pretty.css" media="all" rel="stylesheet">
```

サブスクリプトオペレーターを使用すると、新たな `Media` オブジェクトが戻り値となります -- 使用するメディアのみが含まれています。

### `Media` オブジェクトを結合する

`Media` objects can also be added together. When two `Media` objects are
added, the resulting `Media` object contains the union of the assets
specified by both:

```pycon
>>> 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" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>
<script src="http://static.example.com/whizbang.js"></script>
```

### アセットの順序

DOM に挿入されるアセットの順序が重要になることがあります。例えば、jQuery に依存したスクリプトがあるかもしれません。したがって、結合した `Media` オブジェクトは、各 `Media` クラス内で定義された順序を保持します。

例えば:

```pycon
>>> from django import forms
>>> class CalendarWidget(forms.TextInput):
...     class Media:
...         js = ["jQuery.js", "calendar.js", "noConflict.js"]
...
>>> class TimeWidget(forms.TextInput):
...     class Media:
...         js = ["jQuery.js", "time.js", "noConflict.js"]
...
>>> w1 = CalendarWidget()
>>> w2 = TimeWidget()
>>> print(w1.media + w2.media)
<script src="http://static.example.com/jQuery.js"></script>
<script src="http://static.example.com/calendar.js"></script>
<script src="http://static.example.com/time.js"></script>
<script src="http://static.example.com/noConflict.js"></script>
```

順序が矛盾した `Media` オブジェクトを結合すると `MediaOrderConflictWarning` となります。

## フォームの `Media`

ウィジェットだけでなく、フォームにも `media` の定義を行うことができます。フォーム上での `media` 定義のルールはウィジェットと同じです: 宣言は定数および動的に行えます; パスと継承についてのルールもまったく同じです。

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:

```pycon
>>> 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" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>
<script src="http://static.example.com/whizbang.js"></script>
```

If you want to associate additional assets with a form -- for example,
CSS for form layout -- add a `Media` declaration to the form:

```pycon
>>> 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" media="all" rel="stylesheet">
<link href="http://static.example.com/layout.css" media="all" rel="stylesheet">
<script src="http://static.example.com/animations.js"></script>
<script src="http://static.example.com/actions.js"></script>
<script src="http://static.example.com/whizbang.js"></script>
```
