---
title: "Django の admin サイト"
version: 2.2
locale: ja
source: https://docs.djangoproject.com/ja/2.2/ref/contrib/admin/
canonical: https://djangodocs.dev/ja/2.2/ref/contrib/admin/
---
# Django の admin サイト

Djangoのパワフルな特徴の1つは、自動的に生成されるadminインタフェースです。あなたのモデルクラスからメタデータを読み取り、モデル中心のインタフェースを提供します。このインタフェースのおかげで、ユーザはあなたのサイトのコンテンツを操作することができます。adminサイトのオススメの使い方は、組織内で利用する管理ツールに利用を制限することです。adminサイトは、あなたのサイトのフロントエンドやその周辺を含んだ全体を作成することを意図していません。

adminサイトは、カスタマイゼーションのためのたくさんのフックを持っています。しかしそれらのフックを使う際には気をつけてください。もしあなたが、データベースのテーブルとフィールドを使用しないような、よりプロセス中心のインタフェースを提供する必要があるなら、おそらく自分でビューを書いたほうが良いでしょう。

このドキュメントでは、Django の admin インタフェースを有効にして使用したりカスタマイズする方法について説明します。

## オーバービュー

adminサイトは [`startproject`](/ja/2.2/ref/django-admin/#django-admin-startproject) で使用されるデフォルトのプロジェクトテンプレートで有効になります。

If you're not using the default project template, here are the requirements:

1. Add `'django.contrib.admin'` and its dependencies -
   [`django.contrib.auth`](/ja/2.2/topics/auth/#module-django.contrib.auth), [`django.contrib.contenttypes`](/ja/2.2/ref/contrib/contenttypes/#module-django.contrib.contenttypes),
   [`django.contrib.messages`](/ja/2.2/ref/contrib/messages/#module-django.contrib.messages), and [`django.contrib.sessions`](/ja/2.2/topics/http/sessions/#module-django.contrib.sessions) \- to your
   [`INSTALLED_APPS`](/ja/2.2/ref/settings/#std-setting-INSTALLED_APPS) setting.
2. Configure a [`DjangoTemplates`](/ja/2.2/topics/templates/#django.template.backends.django.DjangoTemplates)
   backend in your [`TEMPLATES`](/ja/2.2/ref/settings/#std-setting-TEMPLATES) setting with
   `django.contrib.auth.context_processors.auth` and
   `django.contrib.messages.context_processors.messages` in
   the `'context_processors'` option of [`OPTIONS`](/ja/2.2/ref/settings/#std-setting-TEMPLATES-OPTIONS).
3. If you've customized the [`MIDDLEWARE`](/ja/2.2/ref/settings/#std-setting-MIDDLEWARE) setting,
   [`django.contrib.auth.middleware.AuthenticationMiddleware`](/ja/2.2/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware) and
   [`django.contrib.messages.middleware.MessageMiddleware`](/ja/2.2/ref/middleware/#django.contrib.messages.middleware.MessageMiddleware) must be
   included.

5. [Hook the admin's URLs into your URLconf](#hooking-adminsite-to-urlconf).

After you've taken these steps, you'll be able to use the admin site by
visiting the URL you hooked it into (`/admin/`, by default).

If you need to create a user to login with, use the [`createsuperuser`](/ja/2.2/ref/django-admin/#django-admin-createsuperuser)
command. By default, logging in to the admin requires that the user has the
[`is_superuser`](/ja/2.2/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser) or [`is_staff`](/ja/2.2/ref/contrib/auth/#django.contrib.auth.models.User.is_staff) attribute set to
`True`.

Finally, determine which of your application's models should be editable in the
admin interface. For each of those models, register them with the admin as
described in [`ModelAdmin`](#django.contrib.admin.ModelAdmin).

### 他のトピック

- [Admin actions](/ja/2.2/ref/contrib/admin/actions/)
- [The Django admin documentation generator](/ja/2.2/ref/contrib/admin/admindocs/)
- [JavaScript customizations in the admin](/ja/2.2/ref/contrib/admin/javascript/)

> **See also**
>
> 本番環境での admin と関連する静的ファイル (画像、JavaScript、CSS) の配信について知りたい場合は、[ファイルを配信する](/ja/2.2/howto/deployment/wsgi/modwsgi/#serving-files) を参照してください。
>
> 問題が解決しない場合は、[FAQ: 管理インタフェース](/ja/2.2/faq/admin/) を参照してみてください。

## `ModelAdmin` のオブジェクト

#### `class ModelAdmin`

`ModelAdmin` クラスは、admin インターフェース内でモデルを表現する方法です。通常、アプリケーション内の `admin.py` に記述されます。`ModelAdmin` のとても簡単な例を見てみましょう:

```
from django.contrib import admin
from myproject.myapp.models import Author

class AuthorAdmin(admin.ModelAdmin):
    pass
admin.site.register(Author, AuthorAdmin)
```

> **いつでも ModelAdmin オブジェクトが必要なのか?**
>
> 上記の例では、ModelAdminクラスはカスタム値を（まだ）定義していません。その結果、デフォルトの管理インターフェースが提供されます。デフォルトのadminインターフェースに満足している場合は、ModelAdminオブジェクトを定義する必要はまったくありません。ModelAdminの記述をせずにモデルクラスを登録できます。上記の例は、次のように簡略化できます。
>
> ```
> from django.contrib import admin
> from myproject.myapp.models import Author
>
> admin.site.register(Author)
> ```

### `register` デコレータ

#### `register(*models, site=django.admin.sites.site)`

`ModelAdmin` を登録するために、デレコータも用意されています:

```
from django.contrib import admin
from .models import Author

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    pass
```

1 つ以上のモデルが与えられ、 `ModelAdmin` に登録されます。カスタムの [`AdminSite`](#django.contrib.admin.AdminSite) を使用している場合、`site` キーワード引数を使って渡してください:

```
from django.contrib import admin
from .models import Author, Editor, Reader
from myproject.admin_site import custom_admin_site

@admin.register(Author, Reader, Editor, site=custom_admin_site)
class PersonAdmin(admin.ModelAdmin):
    pass
```

You can't use this decorator if you have to reference your model admin
class in its `__init__()` method, e.g.
`super(PersonAdmin, self).__init__(*args, **kwargs)`. You can use
`super().__init__(*args, **kwargs)`.

### admin ファイルの発見

[`INSTALLED_APPS`](/ja/2.2/ref/settings/#std-setting-INSTALLED_APPS) 設定内に `'django.contrib.admin'` を記述すると、Django は自動的に各アプリケーション内で `admin` モジュールを探してインポートします。

#### `class apps.AdminConfig`

これは、admin に対するデフォルトの [`AppConfig`](/ja/2.2/ref/applications/#django.apps.AppConfig) クラスです。Django が開始すると [`autodiscover()`](#django.contrib.admin.autodiscover) を呼び出します。

#### `class apps.SimpleAdminConfig`

このクラスは [`AdminConfig`](#django.contrib.admin.apps.AdminConfig) と同じように動作しますが、[`autodiscover()`](#django.contrib.admin.autodiscover) を呼び出しません。

#### `default_site`

> **New in Django 2.1**

これはデフォルトの admin サイトのクラスやサイトインスタンスを返す呼び出し可能オブジェクトへのドット区切りのインポートパスです。デフォルトは `'django.contrib.admin.sites.AdminSite'` です。使い方は [Overriding the default admin site](#overriding-default-admin-site) を参照してください。

#### `autodiscover()`

この関数は、インストールされた各アプリケーション内で `admin` モジュールをインポートするよう試みます。これらのモジュールは admin にモデルが登録されているものと想定されます。

通常、この機能を手動で呼び出す必要はありません。Django が開始するとき [`AdminConfig`](#django.contrib.admin.apps.AdminConfig) が呼び出してくれます。

If you are using a custom `AdminSite`, it is common to import all of the
`ModelAdmin` subclasses into your code and register them to the custom
`AdminSite`. In that case, in order to disable auto-discovery, you should
put `'django.contrib.admin.apps.SimpleAdminConfig'` instead of
`'django.contrib.admin'` in your [`INSTALLED_APPS`](/ja/2.2/ref/settings/#std-setting-INSTALLED_APPS) setting.

### `ModelAdmin` のオプション

`ModelAdmin` は非常に柔軟にできています。インターフェイスをカスタマイズするために、様々なオプションが用意されています。すべてのプションは `ModelAdmin` サブクラスで定義します:

```
from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    date_hierarchy = 'pub_date'
```

#### `ModelAdmin.actions`

チェンジリストページで有効化するアクションのリストです。詳細は [Admin actions](/ja/2.2/ref/contrib/admin/actions/) を参照してください。

#### `ModelAdmin.actions_on_top`

#### `ModelAdmin.actions_on_bottom`

ページ上のどこにアクションバーが表示されかをコントロールします。デフォルトでは、admin チェンジリストはページのトップにアクションを表示します (`actions_on_top = True; actions_on_bottom = False`)。

#### `ModelAdmin.actions_selection_counter`

アクションのドロップダウンの隣に選択用カウンターを表示するかどうかをコントロールします。デフォルトでは、admin チェンジリストは表示するようになっています (`actions_selection_counter = True`)。

#### `ModelAdmin.date_hierarchy`

`date_hierarchy` をモデル内の `DateField` か `DateTimeField` の名前にセットすると、チェンジリストのページがそのフィールドによる日付ベースのドリルダウンナビゲーションを含むようになります。

実装例:

```
date_hierarchy = 'pub_date'
```

`__` ルックアップを使用して、関連するモデルのフィールドを指定することもできます。たとえば:

```
date_hierarchy = 'author__pub_date'
```

この機能は、有効なデータに基づいて、適切に変化させます。たとえば、すべての日付が 1 月に収まっている場合、日のドリルダウンのみを表示します。

> **Note**
>
> `date_hierarchy` は内部的に [`QuerySet.datetimes()`](/ja/2.2/ref/models/querysets/#django.db.models.query.QuerySet.datetimes) を使用します。タイムゾーンサポートが有効 ([`USE_TZ = True`](/ja/2.2/ref/settings/#std-setting-USE_TZ)) な際に注意すべき点について、ドキュメントを参照してください。

#### `ModelAdmin.empty_value_display`

この属性は、からのレコードのフィールドに対するデフォルトの表示値をオーバーライドします (`None`、空の文字列、等)。デフォルト値は `-` (ダッシュ)です。たとえば:

```
from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    empty_value_display = '-empty-'
```

[`AdminSite.empty_value_display`](#django.contrib.admin.AdminSite.empty_value_display) ですべての admin ページもしくは特定のフィールドに対して `empty_value_display` をオーバーライドすることもできます:

```
from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    fields = ('name', 'title', 'view_birth_date')

    def view_birth_date(self, obj):
        return obj.birth_date

    view_birth_date.empty_value_display = '???'
```

#### `ModelAdmin.exclude`

この属性を使用する場合、フォームから除外するフィールドの名称をリストで指定します。

たとえば、以下のモデルを考えてみましょう:

```
from django.db import models

class Author(models.Model):
    name = models.CharField(max_length=100)
    title = models.CharField(max_length=3)
    birth_date = models.DateField(blank=True, null=True)
```

`Author` モデルに対するフォームが `name` と `title` の 2 つのフィールドのみを含むようにしたい場合、以下のように `fields` か `exclude` を指定することになります:

```
from django.contrib import admin

class AuthorAdmin(admin.ModelAdmin):
    fields = ('name', 'title')

class AuthorAdmin(admin.ModelAdmin):
    exclude = ('birth_date',)
```

Author モデルが 3 つのフィールド (`name`、`title`、`birth_date`) しか持っていないので、上記の宣言によって生成されるフォームはまったく同じフィールドを持つことになります。

#### `ModelAdmin.fields`

"add" と "change" 上のフォームでシンプルなレイアウト変更 (有効なフィールドのみを表示する、順序を変える、行にグルーピングする、等) を行うには、`fields` オプションを使用してください。たとえば、[`django.contrib.flatpages.models.FlatPage`](/ja/2.2/ref/contrib/flatpages/#django.contrib.flatpages.models.FlatPage) モデルに対して admin フォームのよりシンプルなバージョンを定義することができます:

```
class FlatPageAdmin(admin.ModelAdmin):
    fields = ('url', 'title', 'content')
```

上記の例では、指定したフィールド ( `url`、`title`、`content`) だけが (結果として) フォーム上で表示されます。`fields` は [`ModelAdmin.readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields) で定義される値を持つことができ、読み込み専用で表示されます。

より複雑なレイアウトを作るには、the [`fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) オプションを参照してください。

`fields` オプションは、[`list_display`](#django.contrib.admin.ModelAdmin.list_display) と同じタイプの値を受け付けますが、カラブルを受け付けないところが異なります。[`readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields) にリスト化されている場合、モデルの名前とモデルの admin メソッドのみが使用されます。

1 つの行に複数のフィールドを表示するには、タプルで囲んでください。この例では、`url` と `title` フィールドが同じ行に表示され、`content` フィールドは次の行に表示されます:

```
class FlatPageAdmin(admin.ModelAdmin):
    fields = (('url', 'title'), 'content')
```

> **ノート**
>
> この `fields` オプションと、次のセクションで説明する [`fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) における `fields` ディクショナリキーは別物です。

`fields` と [`fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) オプションのどちらも存在しない場合、Django はデフォルトで `AutoField` と `editable=True` 以外の各フィールドを、単一のフィールドセットで、モデル内でフィールドが定義されたとおりの順番で表示します。

#### `ModelAdmin.fieldsets`

admin の "add" と "change" ページのレイアウトをコントロールするには、`fieldsets` をセットしてください。

`fieldsets` は、2 タプルのリストで、各 2 タプルは admin フォームページの `<fieldset>` を表します。 (`<fieldset>` はフォームの "section" です。)

2 タプルのフォーマットは `(name, field_options)` で、`name` はフィールドセットのタイトル文字列を表し、`field_options` フィールドセットに関する情報のディクショナリで、表示するフィールドのリストを含みます。

[`django.contrib.flatpages.models.FlatPage`](/ja/2.2/ref/contrib/flatpages/#django.contrib.flatpages.models.FlatPage) モデルを用いた例は以下のようになります:

```
from django.contrib import admin

class FlatPageAdmin(admin.ModelAdmin):
    fieldsets = (
        (None, {
            'fields': ('url', 'title', 'content', 'sites')
        }),
        ('Advanced options', {
            'classes': ('collapse',),
            'fields': ('registration_required', 'template_name'),
        }),
    )
```

これにより、admin ページは以下のような見た目となります:

![](ref/contrib/admin/_images/fieldsets.png)

`fieldsets` と [`fields`](#django.contrib.admin.ModelAdmin.fields) オプションのどちらも存在しない場合、Django はデフォルトで `AutoField` と `editable=True` 以外の各フィールドを、単一のフィールドセットで、モデル内でフィールドが定義されたとおりの順番で表示します。

`field_options` ディクショナリは以下のキーを持つことができます:

- **`fields`**

    フィールドセット内に表示するフィールド名のタプルです。このキーは必須です。

    実装例:

    ```
    {
    'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
    }
    ```

    [`fields`](#django.contrib.admin.ModelAdmin.fields) オプションと同様に、複数のフィールドを 1 行に表示するにはタプルでこれらのフィールドを囲んでください。この例では、`first_name` と `last_name` フィールドが 1 つの行に表示されます:

    ```
    {
    'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
    }
    ```

    `fields` は [`ModelAdmin.readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields) で定義される値を持つことができ、読み込み専用で表示されます。

    `fields` のカラブルの名前を追加した場合、[`fields`](#django.contrib.admin.ModelAdmin.fields) オプションと同じルールが適用されます: カラブルは [`readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields) 内でリスト化される必要があります。
- **`classes`**

    フィールドセットに適用する追加的な CSS を含むリストないしタプルです。

    実装例:

    ```
    {
    'classes': ('wide', 'extrapretty'),
    }
    ```

    `collapse` と\`\`wide\`\`の 2 つの便利なクラスがデフォルトの admin サイトのスタイルシートで定義されています。`collapse` スタイルのフィールドセットは初期状態では admin 内で折りたたまれており、"click to expand" リンクで置き換えられています。 `wide` スタイルのフィールドセットは水平方向の追加的な余白が与えられます。
- **`description`**

    A string of optional extra text to be displayed at the top of each
    fieldset, under the heading of the fieldset. This string is not
    rendered for [`TabularInline`](#django.contrib.admin.TabularInline) due to its
    layout.

    Note that this value is *not* HTML-escaped when it's displayed in
    the admin interface. This lets you include HTML if you so desire.
    Alternatively you can use plain text and
    [`django.utils.html.escape()`](/ja/2.2/ref/utils/#django.utils.html.escape) to escape any HTML special
    characters.

#### `ModelAdmin.filter_horizontal`

デフォルトでは、[`ManyToManyField`](/ja/2.2/ref/models/fields/#django.db.models.ManyToManyField) は `<select multiple>` で admin サイトで表示されます。複数選択のボックスは、たくさんのアイテムを選択するには不向きです。[`ManyToManyField`](/ja/2.2/ref/models/fields/#django.db.models.ManyToManyField) をこのリストに加えると、代わりにかっこよくて控えめな JavaScript の "filter" インターフェースを使用します。非選択および選択済みのオプションは 2 つのボックスに並べて表示されます。垂直方向のインターフェースを使用するには [`filter_vertical`](#django.contrib.admin.ModelAdmin.filter_vertical) を参照してください。

#### `ModelAdmin.filter_vertical`

[`filter_horizontal`](#django.contrib.admin.ModelAdmin.filter_horizontal) と同じですが、フィルタインターフェイスを垂直方向に表示し、非選択のオプションは選択済みのオプションの上部に表示されます。

#### `ModelAdmin.form`

デフォルトではモデルに対して `ModelForm` が動的に生成されます。追加と変更の両方のページで使用されるフォームです。独自の `ModelForm` を定義すれば、追加と変更のページでフォームの挙動を簡単にオーバーライドできます。あるいは、まったく新しいモデルフォームを作る代わりに、[`ModelAdmin.get_form()`](#django.contrib.admin.ModelAdmin.get_form) メソッドを使ってデフォルトのフォームをカスタムすることもできます。

例については [カスタムのバリデーションを admin に追加する](#admin-custom-validation) を参照してください。

> **ノート**
>
> [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) で `Meta.model` 属性を定義した場合、`Meta.fields` 属性 (もしくは `Meta.exclude` 属性) も定義する必要があります。しかし、admin 自身がフィールドを定義する方法を持っているため、`Meta.fields` 属性は無視されます。
>
> `ModelForm` を admin のみで使用する場合は、`ModelAdmin` が使用する正しいモデルを提供するため、`Meta.model` 属性を省略するのが手っ取り早い解決法です。あるいは、`Meta` クラス内で `fields = []` をセットして `ModelForm` のバリデーションの条件を満たすこともできます。

> **ノート**
>
> `ModelForm` と `ModelAdmin` の両方で `exclude` オプションが定義されている場合、`ModelAdmin` は優先順位に従います:
>
> ```
> from django import forms
> from django.contrib import admin
> from myapp.models import Person
>
> class PersonForm(forms.ModelForm):
>
>     class Meta:
>         model = Person
>         exclude = ['name']
>
> class PersonAdmin(admin.ModelAdmin):
>     exclude = ['age']
>     form = PersonForm
> ```
>
> この例では、生成されるフォームで "age" フィールドは除外されますが "name" フィールドは含まれます。

#### `ModelAdmin.formfield_overrides`

admin 内で使用するための [`Field`](/ja/2.2/ref/forms/fields/#django.forms.Field) のうちある程度の部分をオーバーライドする簡単 (だけど汚い) 方法を提供します。`formfield_overrides` はディクショナリで、フィールドクラスの構成時にフィールドに渡す引数のディクショナリをマッピングします。

これでは抽象的すぎるので、具体的な例を見てみましょう。`formfield_overrides` のもっとも一般的な使い道は、特定のタイプのフィールドに対してカスタムしたウィジェットを追加することです。大きなテキストフィールドを使用するために、デフォルトの `<textarea>` の代わりに `RichTextEditorWidget` を使いたいとしましょう。この場合、以下のように記述します:

```
from django.contrib import admin
from django.db import models

# Import our custom widget and our model from where they're defined
from myapp.models import MyModel
from myapp.widgets import RichTextEditorWidget

class MyModelAdmin(admin.ModelAdmin):
    formfield_overrides = {
        models.TextField: {'widget': RichTextEditorWidget},
    }
```

ディクショナリ内のキーは文字列 *ではなく* 実際のフィールドクラスである点に注意してください。値は別のディクショナリです; これらの引数はフォームフィールドの `__init__()` メソッドに渡されます。詳細は [フォーム API](/ja/2.2/ref/forms/api/) を参照してください。

> **Warning**
>
> リレーションフィールド (例えば [`ForeignKey`](/ja/2.2/ref/models/fields/#django.db.models.ForeignKey) や [`ManyToManyField`](/ja/2.2/ref/models/fields/#django.db.models.ManyToManyField)) でカスタムウィジェットを使用したいときは、,  `raw_id_fields`、`radio_fields`、`autocomplete_fields` にそのフィールドの名前を含まないようにしてください。
>
> `formfield_overrides` は、`raw_id_fields`、`radio_fields`、`autocomplete_fields` のどれかがセットされたリレーションフィールドのウィジェットは変更しません。これは、`raw_id_fields`、`radio_fields`、`autocomplete_fields` の 3 つがこれら自身のカスタムウィジェットを暗示するからです。

#### `ModelAdmin.inlines`

後述の [`InlineModelAdmin`](#django.contrib.admin.InlineModelAdmin) オブジェクトと [`ModelAdmin.get_formsets_with_inlines()`](#django.contrib.admin.ModelAdmin.get_formsets_with_inlines) を参照してください。

#### `ModelAdmin.list_display`

admin のチェンジリストページでどのフィールドを表示するかコントロールするために、`list_display` をセットします。

実装例:

```
list_display = ('first_name', 'last_name')
```

`list_display` をセットしない場合、admin サイトは各オブジェクトの `__str__()` 表現を表示する単一の列を表示します。

`list_display` 内で使用できる値には 4 つの種類があります:

- モデルフィールドの名前。たとえば:

  ```
  class PersonAdmin(admin.ModelAdmin):
      list_display = ('first_name', 'last_name')
  ```
- 1 つの引数 (モデルのインスタンス) を受け入れるカラブルです。たとえば:

  ```
  def upper_case_name(obj):
      return ("%s %s" % (obj.first_name, obj.last_name)).upper()
  upper_case_name.short_description = 'Name'

  class PersonAdmin(admin.ModelAdmin):
      list_display = (upper_case_name,)
  ```
- 1 つの引数 (モデルのインスタンス) を受け入れる `ModelAdmin` メソッドを表す文字列です。たとえば:

  ```
  class PersonAdmin(admin.ModelAdmin):
      list_display = ('upper_case_name',)

      def upper_case_name(self, obj):
          return ("%s %s" % (obj.first_name, obj.last_name)).upper()
      upper_case_name.short_description = 'Name'
  ```
- モデルの属性や (必須の引数を持たない) メソッドを表す文字列です。たとえば:

  ```
  from django.contrib import admin
  from django.db import models

  class Person(models.Model):
      name = models.CharField(max_length=50)
      birthday = models.DateField()

      def decade_born_in(self):
          return self.birthday.strftime('%Y')[:3] + "0's"
      decade_born_in.short_description = 'Birth decade'

  class PersonAdmin(admin.ModelAdmin):
      list_display = ('name', 'decade_born_in')
  ```

`list_display` に関する特殊な状況の注意点です:

- フィールドが `ForeignKey` の場合、 Django は関係オブジェクトの `__str__()` を表示します。
- `ManyToManyField` フィールドは、テーブル内で各行に対して個別の SQL ステートメントを実行する可能性があるため、サポートされていません。それでも使いたい場合は、モデルにカスタムメソッドを作成し、そのメソッドの名前を `list_display` に追加してください。 (`list_display` 内でのカスタムメソッドについてより詳しくは下記を参照してください。)
- フィールドが ```BooleanField` の場合、Django は ``True``` か `False` の代わりにかわいい "on" か "off" のアイコンを表示します。
- 与えられた文字列がモデル、`ModelAdmin`、カラブルのどれかの場合、Django はデフォルトで HTML エスケープして出力します。ユーザーの入力をエスケープしたり非エスケープのタグを使う場合、[`format_html()`](/ja/2.2/ref/utils/#django.utils.html.format_html) を使用してください。

  以下は、モデルの例です:

  ```
  from django.contrib import admin
  from django.db import models
  from django.utils.html import format_html

  class Person(models.Model):
      first_name = models.CharField(max_length=50)
      last_name = models.CharField(max_length=50)
      color_code = models.CharField(max_length=6)

      def colored_name(self):
          return format_html(
              '<span style="color: #{};">{} {}</span>',
              self.color_code,
              self.first_name,
              self.last_name,
          )

  class PersonAdmin(admin.ModelAdmin):
      list_display = ('first_name', 'last_name', 'colored_name')
  ```
- これまでの例で見てきたように、カラブル、モデルメソッド、`ModelAdmin` のいずれかを使っているとき、カラブルに `short_description` 属性を追加することでカラムのタイトルをカスタムできます。
- フィールドの値が `None`、空の文字列、エレメントを持たない iterable のいずれかの場合、Django は `-` (ダッシュ) を表示します。この挙動は [`AdminSite.empty_value_display`](#django.contrib.admin.AdminSite.empty_value_display) でオーバーライドできます:

  ```
  from django.contrib import admin

  admin.site.empty_value_display = '(None)'
  ```

  [`ModelAdmin.empty_value_display`](#django.contrib.admin.ModelAdmin.empty_value_display) も使用できます:

  ```
  class PersonAdmin(admin.ModelAdmin):
      empty_value_display = 'unknown'
  ```

  もしくは、フィールドレベルで以下のようにできます:

  ```
  class PersonAdmin(admin.ModelAdmin):
      list_display = ('name', 'birth_date_view')

      def birth_date_view(self, obj):
           return obj.birth_date

      birth_date_view.empty_value_display = 'unknown'
  ```
- 与えられた文字列が、モデルのメソッド、True か False を返す `ModelAdmin`、カラブルのどれかの場合、メソッドに値が `True` の `boolean` 属性を与えれば、Django は かわいい "on" か "off" のアイコンを表示します。

  以下は、モデルの例です:

  ```
  from django.contrib import admin
  from django.db import models

  class Person(models.Model):
      first_name = models.CharField(max_length=50)
      birthday = models.DateField()

      def born_in_fifties(self):
          return self.birthday.strftime('%Y')[:3] == '195'
      born_in_fifties.boolean = True

  class PersonAdmin(admin.ModelAdmin):
      list_display = ('name', 'born_in_fifties')
  ```
- `__str__()` メソッドは、他のモデルメソッドとまったく同様に `list_display` 内でも有効です。つまり、以下のような書き方は完璧に OK です:

  ```
  list_display = ('__str__', 'some_other_field')
  ```
- 通常、実際のデータベースフィールドではない `list_display` の要素は、ソートに使用できません (Django のソートはすべてデータベースレベルで実行されるためです)。

  しかし、`list_display` の要素が特定のデータベースフィールドを表す場合、アイテムの `admin_order_field` 属性をセットすることでこの事実を伝えることができます。

  例:

  ```
  from django.contrib import admin
  from django.db import models
  from django.utils.html import format_html

  class Person(models.Model):
      first_name = models.CharField(max_length=50)
      color_code = models.CharField(max_length=6)

      def colored_first_name(self):
          return format_html(
              '<span style="color: #{};">{}</span>',
              self.color_code,
              self.first_name,
          )

      colored_first_name.admin_order_field = 'first_name'

  class PersonAdmin(admin.ModelAdmin):
      list_display = ('first_name', 'colored_first_name')
  ```

  上記のコードは、admin 内で `colored_first_name` で ソートしようとするとき、`first_name` フィールドで並べ替えるよう Django に伝えます。

  `admin_order_field` を降順で並べ替えるには、フィールド名にハイフンのプレフィクスが使えます。上の例を書き換えると、以下のようになります:

  ```
  colored_first_name.admin_order_field = '-first_name'
  ```

  `admin_order_field` は関係モデルの値でソートするため、クエリ検索をサポートしています。以下の例は list display に "author first name" を含み、first name でソートさせます:

  ```
  class Blog(models.Model):
      title = models.CharField(max_length=255)
      author = models.ForeignKey(Person, on_delete=models.CASCADE)

  class BlogAdmin(admin.ModelAdmin):
      list_display = ('title', 'author', 'author_first_name')

      def author_first_name(self, obj):
          return obj.author.first_name

      author_first_name.admin_order_field = 'author__first_name'
  ```

  `admin_order_field` 内では [Query 表現](/ja/2.2/ref/models/expressions/) を使うことができます。たとえば:

  ```
  from django.db.models import Value
  from django.db.models.functions import Concat

  class Person(models.Model):
      first_name = models.CharField(max_length=50)
      last_name = models.CharField(max_length=50)

      def full_name(self):
          return self.first_name + ' ' + self.last_name
      full_name.admin_order_field = Concat('first_name', Value(' '), 'last_name')
  ```

  > **New in Django 2.1**
  >
  > `admin_order_field` 内での表現のサポートが追加されました。
- Elements of `list_display` can also be properties. Please note however,
  that due to the way properties work in Python, setting
  `short_description` on a property is only possible when using the
  `property()` function and **not** with the `@property` decorator.

  例:

  ```
  class Person(models.Model):
      first_name = models.CharField(max_length=50)
      last_name = models.CharField(max_length=50)

      def my_property(self):
          return self.first_name + ' ' + self.last_name
      my_property.short_description = "Full name of the person"

      full_name = property(my_property)

  class PersonAdmin(admin.ModelAdmin):
      list_display = ('full_name',)
  ```
- The field names in `list_display` will also appear as CSS classes in
  the HTML output, in the form of `column-<field_name>` on each `<th>`
  element. This can be used to set column widths in a CSS file for example.
- Django は、`list_display` の各要素を以下の順番で解釈しようとします:

  - モデルのフィールド。
  - カラブル。
  - `ModelAdmin` 属性を表す文字列。
  - モデル属性を表す文字列。

  たとえば、`first_name` がモデルフィールドと `ModelAdmin` 属性の両方で存在する場合、モデルフィールドの方が使用されます。

#### `ModelAdmin.list_display_links`

[`list_display`](#django.contrib.admin.ModelAdmin.list_display) 内のフィールドにおいて "変更" ページへのリンクをコントロールするには、`list_display_links` を使用してください。

デフォルトでは、チェンジリストページは最初のカラム -- `list_display` で最初に指定したフィールドです -- に各アイテムの変更ページへのリンクが貼られています。しかし、`list_display_links` を使って変更できます:

- リンクを貼らない場合は `None` をセットしてください。
- (`list_display` と同様のフォーマットで) リンクに変換したいカラムのフィールドのリストないしタプルをセットしてください。

  1 つないし複数のフィールドを指定できます。`list_display` にある限り、Django はいくつのフィールドがリンクになろうと気にしません。唯一の要件は、`list_display_links` をこの方式で使いたいときは `list_display` を指定することです。

以下の例では、`first_name` と `last_name` フィールドがチェンジリストページでリンクされます:

```
class PersonAdmin(admin.ModelAdmin):
    list_display = ('first_name', 'last_name', 'birthday')
    list_display_links = ('first_name', 'last_name')
```

以下の例では、チェンジリストページのグリッドにはリンクがなくなります:

```
class AuditEntryAdmin(admin.ModelAdmin):
    list_display = ('timestamp', 'message')
    list_display_links = None
```

#### `ModelAdmin.list_editable`

チェンジリストページ上での編集を有効にしたいモデルのフィールド名のリストを `list_editable` にセットしてください。`list_editable` に指定されたフィールドは、チェンジリストページ上でフォームウィジェットとして表示され、ユーザーは複数の行を一度に編集して保存することができます。

> **Note**
>
> `list_editable` は、他のオプションと特定部分で相互関係にあります; 以下のルールに注意してください:
>
> - `list_editable` 内のすべてのフィールドは `list_display` に含まれている必要があります。表示されていないフィールドは編集できないのです!
> - `list_editable` と `list_display_links` に同じフィールドを同時に指定することはできません -- 1 つのフィールドがフォームとリンクの両方になることはできないからです。
>
> これらのルールを破った場合、バリデーションエラーとなります。

#### `ModelAdmin.list_filter`

admin のチェンジリストページの右サイドバーのフィルタ (以下のような見た目です) を有効化するには、`list_filter` をセットしてください。:

![](ref/contrib/admin/_images/list_filter.png)

`list_filter` は要素のリストかタプルで、各要素は以下のいずれかの種類となります:

- フィールドの名称で、フィールドには `BooleanField`、`CharField`、`DateField`、`DateTimeField`、`IntegerField`、`ForeignKey`、`ManyToManyField` のどれかを指定します。たとえば:

  ```
  class PersonAdmin(admin.ModelAdmin):
      list_filter = ('is_staff', 'company')
  ```

  `list_filter` 内のフィールド名は\`\`\_\_\`\` ルックアップを使って関係先を参照できます。たとえば:

  ```
  class PersonAdmin(admin.UserAdmin):
      list_filter = ('company__name',)
  ```
- `django.contrib.admin.SimpleListFilter` を継承したクラスで、title\` と `parameter_name` 属性を指定し、また `lookups` と `queryset` メソッドをオーバーライドする必要があります。たとえば:

  ```
  from datetime import date

  from django.contrib import admin
  from django.utils.translation import gettext_lazy as _

  class DecadeBornListFilter(admin.SimpleListFilter):
      # Human-readable title which will be displayed in the
      # right admin sidebar just above the filter options.
      title = _('decade born')

      # Parameter for the filter that will be used in the URL query.
      parameter_name = 'decade'

      def lookups(self, request, model_admin):
          """
          Returns a list of tuples. The first element in each
          tuple is the coded value for the option that will
          appear in the URL query. The second element is the
          human-readable name for the option that will appear
          in the right sidebar.
          """
          return (
              ('80s', _('in the eighties')),
              ('90s', _('in the nineties')),
          )

      def queryset(self, request, queryset):
          """
          Returns the filtered queryset based on the value
          provided in the query string and retrievable via
          `self.value()`.
          """
          # Compare the requested value (either '80s' or '90s')
          # to decide how to filter the queryset.
          if self.value() == '80s':
              return queryset.filter(birthday__gte=date(1980, 1, 1),
                                      birthday__lte=date(1989, 12, 31))
          if self.value() == '90s':
              return queryset.filter(birthday__gte=date(1990, 1, 1),
                                      birthday__lte=date(1999, 12, 31))

  class PersonAdmin(admin.ModelAdmin):
      list_filter = (DecadeBornListFilter,)
  ```

  > **Note**
  >
  > 利便性のため、`HttpRequest` オブジェクトが `lookups` と `queryset` メソッドに渡されます。例えば:
  >
  > ```
  > class AuthDecadeBornListFilter(DecadeBornListFilter):
  >
  >     def lookups(self, request, model_admin):
  >         if request.user.is_superuser:
  >             return super().lookups(request, model_admin)
  >
  >     def queryset(self, request, queryset):
  >         if request.user.is_superuser:
  >             return super().queryset(request, queryset)
  > ```
  >
  > Also as a convenience, the `ModelAdmin` object is passed to
  > the `lookups` method, for example if you want to base the
  > lookups on the available data:
  >
  > ```
  > class AdvancedDecadeBornListFilter(DecadeBornListFilter):
  >
  >     def lookups(self, request, model_admin):
  >         """
  >         Only show the lookups if there actually is
  >         anyone born in the corresponding decades.
  >         """
  >         qs = model_admin.get_queryset(request)
  >         if qs.filter(birthday__gte=date(1980, 1, 1),
  >                       birthday__lte=date(1989, 12, 31)).exists():
  >             yield ('80s', _('in the eighties'))
  >         if qs.filter(birthday__gte=date(1990, 1, 1),
  >                       birthday__lte=date(1999, 12, 31)).exists():
  >             yield ('90s', _('in the nineties'))
  > ```
- タプルで、最初の要素がフィールド名で、2 番目の要素が `django.contrib.admin.FieldListFilter` を継承したクラスです。たとえば:

  ```
  class PersonAdmin(admin.ModelAdmin):
      list_filter = (
          ('is_staff', admin.BooleanFieldListFilter),
      )
  ```

  `RelatedOnlyFieldListFilter` を使って、関係内に含まれたオブジェクトへの関係モデルの選択肢を制限することができます:

  ```
  class BookAdmin(admin.ModelAdmin):
      list_filter = (
          ('author', admin.RelatedOnlyFieldListFilter),
      )
  ```

  `author` が `User` モデルへの `ForeignKey` と仮定すると、`list_filter` の選択肢が全ユーザーではなく book を書いたことがあるユーザーだけに絞られます。

  > **Note**
  >
  > The `FieldListFilter` API is considered internal and might be
  > changed.

List filter's typically appear only if the filter has more than one choice.
A filter's `has_output()` method controls whether or not it appears.

It is possible to specify a custom template for rendering a list filter:

```
class FilterWithCustomTemplate(admin.SimpleListFilter):
    template = "custom_template.html"
```

具体的な例については、Django により提供されるデフォルトのテンプレート (`admin/filter.html`) を参照してください。

#### `ModelAdmin.list_max_show_all`

"Show all" の admin チェンジリストページで表示するアイテム数をコントロールするには、`list_max_show_all` をセットしてください。チェンジリストページの "Show all" リンクは、この設定値以下の場合のみ表示されます。デフォルトでは\`\`200\`\` にセットされています。

#### `ModelAdmin.list_per_page`

ページづけられた admin のチェンジリストページに表示するアイテム数をコントロールするには、`list_per_page` をセットしてください。デフォルトでは `100` にセットされています。

#### `ModelAdmin.list_select_related`

admin のチェンジリストページでオブジェクトのリストを検索するときに [`select_related()`](/ja/2.2/ref/models/querysets/#django.db.models.query.QuerySet.select_related) を使用するよう Django に伝えるには、`list_select_related` をセットしてください。これにより多くのデータベースクエリを削減できます。

値は真偽値、リスト、タプルのどれかである必要があります。デフォルトは `False` です。

値が `True` のとき、常に `select_related()` が呼ばれます。`False` のときは、`ForeignKey` が存在する場合 Django は `list_display` を参照して `select_related()` を呼び出します。

よりきめ細やかにコントロールする場合は、`list_select_related` の値にタプル (ないしリスト) を使用してください。空のタプルは、Django が `select_related` を一切呼び出さないようにします。他のタプルは、パラメータとして直接 `select_related` に渡されます。例えば:

```
class ArticleAdmin(admin.ModelAdmin):
    list_select_related = ('author', 'category')
```

これは `select_related('author', 'category')` を呼び出します。

リクエストに基づいた動的な値を指定する場合は、[`get_list_select_related()`](#django.contrib.admin.ModelAdmin.get_list_select_related) メソッドを実装できます。

> **Note**
>
> `ModelAdmin` ignores this attribute when
> [`select_related()`](/ja/2.2/ref/models/querysets/#django.db.models.query.QuerySet.select_related) was already
> called on the changelist's `QuerySet`.

#### `ModelAdmin.ordering`

Django の admin ビューでオブジェクトのリストをどのように並べるかを指定するには、 `ordering` をセットしてください。モデルの [`ordering`](/ja/2.2/ref/models/options/#django.db.models.Options.ordering) パラメータと同じフォーマットでリストかタプルを与えてください。

指定がない場合、Django admin はモデルのデフォルトの並び順を使用します。

動的な並び順を指定する場合 (例えばユーザーや言語に応じる場合など)、[`get_ordering()`](#django.contrib.admin.ModelAdmin.get_ordering) メソッドを実装できます。

> **Performance considerations with ordering and sorting**
>
> To ensure a deterministic ordering of results, the changelist adds
> `pk` to the ordering if it can't find a single or unique together set
> of fields that provide total ordering.
>
> For example, if the default ordering is by a non-unique `name` field,
> then the changelist is sorted by `name` and `pk`. This could
> perform poorly if you have a lot of rows and don't have an index on
> `name` and `pk`.

#### `ModelAdmin.paginator`

ページづけに使われる paginator クラスです。デフォルトでは [`django.core.paginator.Paginator`](/ja/2.2/topics/pagination/#django.core.paginator.Paginator) が使われます。カスタムの paginator クラスが [`django.core.paginator.Paginator`](/ja/2.2/topics/pagination/#django.core.paginator.Paginator) と同じコンストラクタインターフェースを持たない場合、[`ModelAdmin.get_paginator()`](#django.contrib.admin.ModelAdmin.get_paginator) に対する実装も行う必要があります。

#### `ModelAdmin.prepopulated_fields`

Set `prepopulated_fields` to a dictionary mapping field names to the
fields it should prepopulate from:

```
class ArticleAdmin(admin.ModelAdmin):
    prepopulated_fields = {"slug": ("title",)}
```

When set, the given fields will use a bit of JavaScript to populate from
the fields assigned. The main use for this functionality is to
automatically generate the value for `SlugField` fields from one or more
other fields. The generated value is produced by concatenating the values
of the source fields, and then by transforming that result into a valid
slug (e.g. substituting dashes for spaces; lowercasing ASCII letters; and
removing various English stop words such as 'a', 'an', 'as', and similar).

Prepopulated fields aren't modified by JavaScript after a value has been
saved. It's usually undesired that slugs change (which would cause an
object's URL to change if the slug is used in it).

`prepopulated_fields` は `DateTimeField`、`ForeignKey`、`OneToOneField`、`ManyToManyField` フィールドを受け入れません。

#### `ModelAdmin.preserve_filters`

admin は現在、オブジェクトの作成、編集、削除を行った後もリストビューのフィルタを維持します。この属性を `False` にセットすると、フィルタをクリアする以前の挙動に戻すことができます。

#### `ModelAdmin.radio_fields`

デフォルトでは、`ForeignKey` や `choices` がセットされたフィールドに対して、Django の admin はセレクトボックスのインターフェース (\<select\>) を使用します。フィールドが `radio_fields` に指定された場合、Django は代わりに ラジオボタンのインターフェースを使用します。`group` が `Person` モデルの `ForeignKey` だと仮定すると:

```
class PersonAdmin(admin.ModelAdmin):
    radio_fields = {"group": admin.VERTICAL}
```

`django.contrib.admin` モジュールから `HORIZONTAL` か `VERTICAL` のどちらを使用するか選択してください。

`ForeignKey` ないし `choices` がセットされたフィールド以外は、`radio_fields` に含めないでください。

#### `ModelAdmin.autocomplete_fields`

`autocomplete_fields` は、[Select2](https://select2.org/) オートコンプリート入力に変更したい `ForeignKey` ないし `ManyToManyField` フィールドのリストです。

デフォルトでは、これらのフィールドに対して admin はセレクトボックスのインターフェース (`<select>`) を使用します。ドロップダウン内に表示する関係インスタンスをすべて選択するオーバーヘッドから逃れたいこともあるでしょう。

Select2 入力はデフォルトの入力と似た見た目ですが、非同期的にオプションを読み込む検索機能を持っています。こちらの方が高速で、特に関係モデルに多くのインスタンスがある場合にはユーザーフレンドリーです。

オートコンプリート検索は関係オブジェクトの `ModelAdmin` を使用するため、`ModelAdmin` に [`search_fields`](#django.contrib.admin.ModelAdmin.search_fields) を定義する必要があります。

認証されていないデータが表示されるのを防ぐため、オートコンプリートを使うには、ユーザーは関係オブジェクトに対する `view` か `change` 権限を持っている必要があります。

結果の並べ替えおよびページづけは、関係する `ModelAdmin` の [`get_ordering()`](#django.contrib.admin.ModelAdmin.get_ordering) と [`get_paginator()`](#django.contrib.admin.ModelAdmin.get_paginator) メソッドでコントロールします。

以下の例では、`ChoiceAdmin` フィールドは `Question` への `ForeignKey` に対するオートコンプリートフィールドを持ちます。結果は `question_text` フィールドによりフィルタされ、また\`\`date\_created\`\` フィールドにより並べ替えられます:

```
class QuestionAdmin(admin.ModelAdmin):
    ordering = ['date_created']
    search_fields = ['question_text']

class ChoiceAdmin(admin.ModelAdmin):
    autocomplete_fields = ['question']
```

> **巨大なデータセットに対するパフォーマンスの考察**
>
> [`ModelAdmin.ordering`](#django.contrib.admin.ModelAdmin.ordering) を使った並べ替えは、巨大なクエリセットは遅くなるため、パフォーマンスの問題の原因となります。
>
> また、検索フィールドがデータベースによるインデックス化がされていないフィールドを含む場合、巨大なテーブルでは貧弱なパフォーマンスしか発揮できなくなってしまいます。
>
> このような場合は、フルテキストのインデックスサーチを使用した独自の [`ModelAdmin.get_search_results()`](#django.contrib.admin.ModelAdmin.get_search_results) 実装を記述するのがよいでしょう。
>
> また、デフォルトの paginator は常に  `count()` を発行するため、巨大なテーブルでは `Paginator` を変更するのがお勧めです。例えば、`Paginator.count` プロパティのデフォルトの実装をオーバーライドできます。

#### `ModelAdmin.raw_id_fields`

デフォルトでは、`ForeignKey` のフィールドに対して Django の admin はセレクトボックスのインターフェース (`<select>`) を使用します。ドロップダウン内に表示する関係インスタンスをすべて選択するオーバーヘッドから逃れたいこともあるでしょう。

`raw_id_fields` は、`ForeignKey` や `ManyToManyField` に対する `Input` ウィジェットを適用したいフィールドのリストです:

```
class ArticleAdmin(admin.ModelAdmin):
    raw_id_fields = ("newspaper",)
```

`raw_id_fields` `Input` ウィジェットには、`ForeignKey` の場合はプライマリキーを、`ManyToManyField` の場合はカンマで区切った値のリストを入力します。`raw_id_fields` ウィジェットには、ユーザーが値を検索および選択できるよう、隣にルーペボタンがあります:

![](ref/contrib/admin/_images/raw_id_fields.png)

#### `ModelAdmin.readonly_fields`

デフォルトでは、すべてのフィールドが編集可能となっています。このオプションに含まれるフィールド (`list` か `tuple` で指定します) は、データをそのまま表示するだけで編集できなくなります; また、追加と編集に使われる [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) からも除外されます。[`ModelAdmin.fields`](#django.contrib.admin.ModelAdmin.fields) か [`ModelAdmin.fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) を指定した場合、read-only のフィールドは表示のために存在している必要があります (存在しなければ無視されます)。

[`ModelAdmin.fields`](#django.contrib.admin.ModelAdmin.fields) や [`ModelAdmin.fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) で明示的に並び順を定義しないで `readonly_fields` を使った場合、これらのフィールドはすべての編集可能なフィールドの後に表示されます。

read-only のフィールドはモデルのフィールドからデータを表示するだけではなく、モデルや\`\`ModelAdmin\`\` クラス自身のメソッドの出力を表示させることもできます。これは [`ModelAdmin.list_display`](#django.contrib.admin.ModelAdmin.list_display) の挙動に似ています。これにより、編集中のオブジェクトのステータスのフィードバックを admin インターフェースに与えることが簡単にできるようになります。例えば:

```
from django.contrib import admin
from django.utils.html import format_html_join
from django.utils.safestring import mark_safe

class PersonAdmin(admin.ModelAdmin):
    readonly_fields = ('address_report',)

    def address_report(self, instance):
        # assuming get_full_address() returns a list of strings
        # for each line of the address and you want to separate each
        # line by a linebreak
        return format_html_join(
            mark_safe('<br>'),
            '{}',
            ((line,) for line in instance.get_full_address()),
        ) or mark_safe("<span class='errors'>I can't determine this address.</span>")

    # short_description functions like a model field's verbose_name
    address_report.short_description = "Address"
```

#### `ModelAdmin.save_as`

admin のチェンジーフォームで "新規に保存" 機能を有効化するには `save_as` をセットしてください。

通常、オブジェクトには 3 つの保存オプションがあります: "保存"、"保存して編集を続ける"、"保存して 1 つ追加" です。`save_as` が `True` の場合、"保存して 1 つ追加" が "新規に保存" ボタンに変更され、既存のオブジェクトを変更するのではなく (新しい ID) で新規のオブジェクトが作成されるようになります。

デフォルトでは `save_as` は `False` にセットされています。

#### `ModelAdmin.save_as_continue`

[`save_as=True`](#django.contrib.admin.ModelAdmin.save_as) のとき、新規オブジェクトを保存した後のデフォルトのリダイレクト先はそのオブジェクトの変更ビューです。`save_as_continue=False` にセットすると、リダイレクト先がチェンジリストビューになります。

デフォルトでは `save_as_continue` は `True` にセットされています。

#### `ModelAdmin.save_on_top`

admin のチェンジフォームの上部に保存ボタンを追加するには `save_on_top` をセットしてください。

通常、保存ボタンはフォームの下部のみに表示されます。`save_on_top` をセットすると、ボタンは上部と下部の両方に表示されるようになります。

デフォルトでは `save_on_top` は `False` にセットされています。

#### `ModelAdmin.search_fields`

admin のチェンジリストページで検索ボックスを有効化するには `search_fields` をセットしてください。セットするのはフィールド名のリストで、ここで指定したフィールドはテキストボックス内での検索クエリの対象となります。

指定するフィールドの種類は、`CharField` や `TextField` といったテキストフィールドである必要があります。検索 API の "follow" 記法を使えば `ForeignKey` や `ManyToManyField` を検索することもできます:

```
search_fields = ['foreign_key__related_fieldname']
```

例えば、著者の情報を持つブログエントリーの場合、以下の定義により、著者の E メールアドレスによるブログエントリーの検索が可能となります:

```
search_fields = ['user__email']
```

検索ボックスで検索が行われるとき、Django は検索クエリを単語に分割し、([`icontains`](/ja/2.2/ref/models/querysets/#std-fieldlookup-icontains) 検索を使って) 大文字と小文字を区別して、各単語を含むオブジェクトを返します。各単語は最低 1 つの `search_fields` に含まれている必要があります。例えば、`search_fields` が `['first_name', 'last_name']` にセットされ、ユーザーが `john lennon` と検索した場合、Django は SQL の `WHERE` 節と同等の検索を実行します:

```
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
```

検索に `icontains` を使いたくない場合、フィールドに検索方法を追加することで、好きな方法を使うことができます。例えば、`search_fields` に `['first_name__exact']` をセットすれば [`exact`](/ja/2.2/ref/models/querysets/#std-fieldlookup-exact) を使えます。

前述の通り、クエリ条件は分割されて AND で再構成されるので、[`exact`](/ja/2.2/ref/models/querysets/#std-fieldlookup-exact) を使った検索は単一の単語の検索でしか機能しません。これは、すべての単語がまったく同じ場合以外、2 語以上が完全一致することはないからです。

> **New in Django 2.1**
>
> フィールドの検索方法を指定する機能が追加されました。

いくつかの (古い) ショートカットを使って、フィールドの検索方法を指定することもできます。以下の文字で `search_fields` 内のフィールドにプレフィックスを追加できます。これはフィールドに `__<lookup>` を追加するのと同等です:

| プレフィックス | 検索方法 |
| --- | --- |
| ^ | [`startswith`](/ja/2.2/ref/models/querysets/#std-fieldlookup-startswith) |
| = | [`iexact`](/ja/2.2/ref/models/querysets/#std-fieldlookup-iexact) |
| @ | [`search`](/ja/2.2/ref/contrib/postgres/search/#std-fieldlookup-search) |
| None | [`icontains`](/ja/2.2/ref/models/querysets/#std-fieldlookup-icontains) |

検索方法をカスタムする必要がある場合は、[`ModelAdmin.get_search_results()`](#django.contrib.admin.ModelAdmin.get_search_results) を使って追加的もしくは代替の検索方法を提供することができます。

#### `ModelAdmin.show_full_result_count`

フィルタリングされた admin ページにオブジェクトのカウント (例: `99 results (103 total)`) を表示するかどうかをコントロールするには、`show_full_result_count` をセットしてください。`False` にセットすると、代わりに `99 results (Show all)` のような文字列が表示されるようになります。

デフォルトの `show_full_result_count=True` は、テーブル内の全アイテムをカウントするクエリを発行するため、多くの行を含むテーブルではパフォーマンス低下の原因となります。

#### `ModelAdmin.sortable_by`

> **New in Django 2.1**

デフォルトでは、チェンジリストページでは [`list_display`](#django.contrib.admin.ModelAdmin.list_display) で指定したすべてのモデルフィールド (と `admin_order_field` プロパティを持つカラブル) で並び替えが可能です。

特定のカラムでの並び替えを無効化したい場合、```sortable_by``に :attr:`list_display` サブセットのコレクション (例: ``list```、`tuple`、`set`) をセットしてください。空のコレクションを指定すると、すべてのカラムで並び替え不可となります。

リストを動的に指定する必要があるときは、代わりに [`get_sortable_by()`](#django.contrib.admin.ModelAdmin.get_sortable_by) メソッドを実装してください。

#### `ModelAdmin.view_on_site`

"サイトで見る" リンクを表示するか否かをコントロールするには、`view_on_site` をセットしてください。このリンクは保存されたオブジェクトを表示できる URL に誘導します。

値は、真偽値かカラブルで指定します。`True` (デフォルトです) の場合、オブジェクトの [`get_absolute_url()`](/ja/2.2/ref/models/instances/#django.db.models.Model.get_absolute_url) メソッドが使われ、URLが生成されます。

モデルが [`get_absolute_url()`](/ja/2.2/ref/models/instances/#django.db.models.Model.get_absolute_url) メソッドを持っていても "サイトで見る" ボタンを表示したくない場合は、`view_on_site` に `False` をセットしてください:

```
from django.contrib import admin

class PersonAdmin(admin.ModelAdmin):
    view_on_site = False
```

カラブルの場合、引数にモデルのインスタンスを受け入れます。例えば:

```
from django.contrib import admin
from django.urls import reverse

class PersonAdmin(admin.ModelAdmin):
    def view_on_site(self, obj):
        url = reverse('person-detail', kwargs={'slug': obj.slug})
        return 'https://example.com' + url
```

#### カスタムテンプレートのオプション

[Overriding admin templates](#admin-overriding-templates) セクションでは、デフォルトの admin テンプレートをオーバーライドないし拡張する方法を説明しています。[`ModelAdmin`](#django.contrib.admin.ModelAdmin) ビューで使用されるデフォルトのテンプレートをオーバーライドするには、以下のオプションを使用してください:

#### `ModelAdmin.add_form_template`

カスタムンテンプレートの絶対パスで、[`add_view()`](#django.contrib.admin.ModelAdmin.add_view) で使われます。

#### `ModelAdmin.change_form_template`

カスタムンテンプレートの絶対パスで、[`change_view()`](#django.contrib.admin.ModelAdmin.change_view) で使われます。

#### `ModelAdmin.change_list_template`

カスタムンテンプレートの絶対パスで、[`changelist_view()`](#django.contrib.admin.ModelAdmin.changelist_view) で使われます。

#### `ModelAdmin.delete_confirmation_template`

カスタムンテンプレートの絶対パスで、1 つ以上のオブジェクトを削除するときに確認ページを表示するために、[`delete_view()`](#django.contrib.admin.ModelAdmin.delete_view) で使われます。

#### `ModelAdmin.delete_selected_confirmation_template`

カスタムンテンプレートの絶対パスで、1 つ以上のオブジェクトを削除するときに確認ページを表示するために、`delete_selected` アクションメソッドで使われます。[actions documentation](/ja/2.2/ref/contrib/admin/actions/) を参照してください。

#### `ModelAdmin.object_history_template`

カスタムンテンプレートの絶対パスで、[`history_view()`](#django.contrib.admin.ModelAdmin.history_view) で使われます。

#### `ModelAdmin.popup_response_template`

カスタムンテンプレートの絶対パスで、[`response_add()`](#django.contrib.admin.ModelAdmin.response_add)、[`response_change()`](#django.contrib.admin.ModelAdmin.response_change)、[`response_delete()`](#django.contrib.admin.ModelAdmin.response_delete) の 3 つで使われます。

### `ModelAdmin` のメソッド

> **Warning**
>
> [`ModelAdmin.save_model()`](#django.contrib.admin.ModelAdmin.save_model) や [`ModelAdmin.delete_model()`](#django.contrib.admin.ModelAdmin.delete_model) をオーバーライドするときは、オブジェクトの保存や削除の処理を記述する必要があります。これは、制限を設けるためではなく、追加的な操作を可能にするための仕様です。

#### `ModelAdmin.save_model(request, obj, form, change)`

`save_model` メソッドには、`HttpRequest`、モデルのインスタンス、`ModelForm` のインスタンス、追加か変更かを表す真偽値が渡されます。このメソッドをオーバーライドすると、保存の前後に操作を追加できます。`super().save_model()` を呼び出して、[`Model.save()`](/ja/2.2/ref/models/instances/#django.db.models.Model.save) を使ってオブジェクトを保存してください。

例えば、保存前にオブジェクトに `request.user` を追加するには:

```
from django.contrib import admin

class ArticleAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        obj.user = request.user
        super().save_model(request, obj, form, change)
```

#### `ModelAdmin.delete_model(request, obj)`

`delete_model` には、`HttpRequest` とモデルのインスタンスが渡されます。このメソッドをオーバーライドすると、削除の前後に操作を追加できます。`super().delete_model()` を呼び出して、[`Model.delete()`](/ja/2.2/ref/models/instances/#django.db.models.Model.delete) を使ってオブジェクトを削除してください。

#### `ModelAdmin.delete_queryset(request, queryset)`

> **New in Django 2.1**

`delete_queryset()` には、`HttpRequest` と削除するオブジェクトの `QuerySet` が渡されます。このメソッドをオーバーライドすると、"選択したオブジェクトの削除" [アクション](/ja/2.2/ref/contrib/admin/actions/) に対する削除のプロセスをカスタムできます。

#### `ModelAdmin.save_formset(request, form, formset, change)`

`save_formset` メソッドには、`HttpRequest`、親 `ModelForm` のインスタンス、親オブジェクトの追加か変更かを表す真偽値が与えられます。

例えば、変更のあったフォームセットのモデルのインスタンスそれぞれに `request.user` を追加するには:

```
class ArticleAdmin(admin.ModelAdmin):
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.user = request.user
            instance.save()
        formset.save_m2m()
```

[Saving objects in the formset](/ja/2.2/topics/forms/modelforms/#saving-objects-in-the-formset) もご覧ください。

#### `ModelAdmin.get_ordering(request)`

`get_ordering` メソッドは引数に `request` を取り、[`ordering`](#django.contrib.admin.ModelAdmin.ordering) のときと同じような `list` か `tuple` を返すことが期待されます。例えば:

```
class PersonAdmin(admin.ModelAdmin):

    def get_ordering(self, request):
        if request.user.is_superuser:
            return ['name', 'rank']
        else:
            return ['name']
```

#### `ModelAdmin.get_search_results(request, queryset, search_term)`

`get_search_results` メソッドは、検索語と一致するオブジェクトを表示するための、オブジェクトのリストを修正します。リクエスト、現在のフィルタを適用するクエリセット、 ユーザーが入力した検索語を受け取ります。 検索を実行するために修正されたクエリセットと、結果に重複があるかどうかを表す真偽値を含むタプルを返します。

デフォルトの実装では、[`ModelAdmin.search_fields`](#django.contrib.admin.ModelAdmin.search_fields) に含まれるフィールドを検索します。

このメソッドは、独自の検索方法でオーバーライドすることができます。例えば、数値のフィールドで検索したり、Solr や Haystack といった外部のツールを使うことができます。独自の検索方法によって実装されたクエリセットの変更が結果に重複を生じさせるかを確認し、返値の 2 番目の要素に `True` を返す必要があります。

例えば、`name` と `age` で検索するには、以下のように使います:

```
class PersonAdmin(admin.ModelAdmin):
    list_display = ('name', 'age')
    search_fields = ('name',)

    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super().get_search_results(request, queryset, search_term)
        try:
            search_term_as_int = int(search_term)
        except ValueError:
            pass
        else:
            queryset |= self.model.objects.filter(age=search_term_as_int)
        return queryset, use_distinct
```

この実装は、数値フィールドに対して文字列比較を行う `search_fields = ('name', '=age')` に比べて、春香に効率的です... 例えば PostgreSQL では `... OR UPPER("polls_choice"."votes"::text) = UPPER('4')` となります。

#### `ModelAdmin.save_related(request, form, formsets, change)`

`save_related` メソッドには、`HttpRequest`、親 `ModelForm` のインスタンス、インラインフォームセットのリスト、親の追加か変更かを表す真偽値が与えられます。このメソッドで、保存の前後に親に対する関係オブジェクトに対する操作を追加できます。この時点では親オブジェクトとそのフォームはすでに保存されていることに注意してください。

#### `ModelAdmin.get_autocomplete_fields(request)`

`get_autocomplete_fields()` メソッドには、`HttpRequest` が渡され、上述の [`ModelAdmin.autocomplete_fields`](#django.contrib.admin.ModelAdmin.autocomplete_fields) セクションで説明した通りオートコンプリートウィジェットで表示するフィールドの名前の `list` か `tuple` を返すことが期待されます。

#### `ModelAdmin.get_readonly_fields(request, obj=None)`

`get_readonly_fields` メソッドには、`HttpRequest` と編集対象の `obj` (ないし新規追加用の `None`) が渡され、上述の [`ModelAdmin.readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields) セクションで説明した通り、読み込み専用で表示するフィールドの名前の `list` か `tuple` を返すことが期待されます。

#### `ModelAdmin.get_prepopulated_fields(request, obj=None)`

`get_prepopulated_fields` メソッドには、`HttpRequest` と編集対象の `obj` (ないし新規追加用の `None`) が渡され、上述の [`ModelAdmin.prepopulated_fields`](#django.contrib.admin.ModelAdmin.prepopulated_fields) セクションで説明した通り `dictionary` を返すことが期待されます。

#### `ModelAdmin.get_list_display(request)`

`get_list_display` メソッドには、`HttpRequest` が渡され、上述の [`ModelAdmin.list_display`](#django.contrib.admin.ModelAdmin.list_display) セクションで説明した通りチェンジリストビューで表示するフィールドの名前の `list` か `tuple` を返すことが期待されます。

#### `ModelAdmin.get_list_display_links(request, list_display)`

`get_list_display_links` メソッドには、`HttpRequest` と [`ModelAdmin.get_list_display()`](#django.contrib.admin.ModelAdmin.get_list_display) によって返された `list` ないし `tuple` が渡されます。上述の [`ModelAdmin.list_display_links`](#django.contrib.admin.ModelAdmin.list_display_links) セクションで説明した通り、チェンジリストで変更ビューにリンクを貼りたいフィールドの名前の `list` か `tuple`、もしくは `None` を返すことが期待されます。

#### `ModelAdmin.get_exclude(request, obj=None)`

`get_exclude` メソッドには、`HttpRequest` と編集対象の `obj` (ないし新規追加用の `None`) が渡され、上述の [`ModelAdmin.exclude`](#django.contrib.admin.ModelAdmin.exclude) セクションで説明した通りフィールドのリストを返すことが期待されます。

#### `ModelAdmin.get_fields(request, obj=None)`

`get_fields` メソッドには、`HttpRequest` と編集対象の `obj` (ないし新規追加用の `None`) が渡され、上述の [`ModelAdmin.fields`](#django.contrib.admin.ModelAdmin.fields) セクションで説明した通りフィールドのリストを返すことが期待されます。

#### `ModelAdmin.get_fieldsets(request, obj=None)`

`get_fieldsets` メソッドには、`HttpRequest` と編集対象の `obj` (ないし新規追加用の `None`) が渡され、2 タプルのリストを返すことが期待されます。各 2 タプルは、上述の [`ModelAdmin.fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) セクションで説明した通り admin のフォームページ上の `<fieldset>` を表します。

#### `ModelAdmin.get_list_filter(request)`

`get_list_filter` メソッドには、`HttpRequest` が渡され、[`list_filter`](#django.contrib.admin.ModelAdmin.list_filter) 属性のときと同じ種類のシーケンス型を返すことが期待されます。

#### `ModelAdmin.get_list_select_related(request)`

`get_list_select_related` メソッドには、`HttpRequest` が渡され、真偽値もしくは [`ModelAdmin.list_select_related`](#django.contrib.admin.ModelAdmin.list_select_related) と同様のリストを返す必要があります。

#### `ModelAdmin.get_search_fields(request)`

`get_search_fields` メソッドには、`HttpRequest` が渡され、[`search_fields`](#django.contrib.admin.ModelAdmin.search_fields) 属性のときと同じ種類のシーケンス型を返すことが期待されます。

#### `ModelAdmin.get_sortable_by(request)`

> **New in Django 2.1**

`get_list_display` メソッドには、`HttpRequest` が渡され、チェンジリストページ並び替え可能にするフィールドの名前の コレクション (例: `list`、`tuple`、`set`) を返すことが期待されます。

デフォルトの実装では、セットされている場合は [`sortable_by`](#django.contrib.admin.ModelAdmin.sortable_by) を返します。セットされていなければ [`get_list_display()`](#django.contrib.admin.ModelAdmin.get_list_display) を参照します。

例えば、1 つ以上のカラムを並び替え不可にするには:

```
class PersonAdmin(admin.ModelAdmin):

    def get_sortable_by(self, request):
        return {*self.get_list_display(request)} - {'rank'}
```

#### `ModelAdmin.get_inline_instances(request, obj=None)`

The `get_inline_instances` method is given the `HttpRequest` and the
`obj` being edited (or `None` on an add form) and is expected to return
a `list` or `tuple` of [`InlineModelAdmin`](#django.contrib.admin.InlineModelAdmin)
objects, as described below in the [`InlineModelAdmin`](#django.contrib.admin.InlineModelAdmin)
section. For example, the following would return inlines without the default
filtering based on add, change, delete, and view permissions:

```
class MyModelAdmin(admin.ModelAdmin):
    inlines = (MyInline,)

    def get_inline_instances(self, request, obj=None):
        return [inline(self.model, self.admin_site) for inline in self.inlines]
```

このメソッドをオーバーライドする場合、返値となるインラインは [`inlines`](#django.contrib.admin.ModelAdmin.inlines) で定義したクラスのインスタンスにしてください。間違えると、関係オブジェクトを追加する際に "Bad Request" が発生する可能性があります。

#### `ModelAdmin.get_urls()`

`ModelAdmin` の `get_urls` メソッドは、URLconf と同じ方法で、その ModelAdmin に対して使用される URL を返します。したがって、[URL ディスパッチャ](/ja/2.2/topics/http/urls/) と同じように拡張することができます:

```
from django.contrib import admin
from django.template.response import TemplateResponse
from django.urls import path

class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.my_view),
        ]
        return my_urls + urls

    def my_view(self, request):
        # ...
        context = dict(
           # Include common variables for rendering the admin template.
           self.admin_site.each_context(request),
           # Anything else you want in the context...
           key=value,
        )
        return TemplateResponse(request, "sometemplate.html", context)
```

admin のレイアウトを使用したい場合、`admin/base_site.html` を extend してください:

```html+django
{% extends "admin/base_site.html" %}
{% block content %}
...
{% endblock %}
```

> **Note**
>
> Notice that the custom patterns are included *before* the regular admin
> URLs: the admin URL patterns are very permissive and will match nearly
> anything, so you'll usually want to prepend your custom URLs to the
> built-in ones.
>
> In this example, `my_view` will be accessed at
> `/admin/myapp/mymodel/my_view/` (assuming the admin URLs are included
> at `/admin/`.)

However, the `self.my_view` function registered above suffers from two
problems:

- It will *not* perform any permission checks, so it will be accessible
  to the general public.
- It will *not* provide any header details to prevent caching. This means
  if the page retrieves data from the database, and caching middleware is
  active, the page could show outdated information.

Since this is usually not what you want, Django provides a convenience
wrapper to check permissions and mark the view as non-cacheable. This
wrapper is `AdminSite.admin_view()` (i.e. `self.admin_site.admin_view`
inside a `ModelAdmin` instance); use it like so:

```
class MyModelAdmin(admin.ModelAdmin):
    def get_urls(self):
        urls = super().get_urls()
        my_urls = [
            path('my_view/', self.admin_site.admin_view(self.my_view))
        ]
        return my_urls + urls
```

Notice the wrapped view in the fifth line above:

```
path('my_view/', self.admin_site.admin_view(self.my_view))
```

This wrapping will protect `self.my_view` from unauthorized access and
will apply the [`django.views.decorators.cache.never_cache()`](/ja/2.2/topics/http/decorators/#django.views.decorators.cache.never_cache) decorator to
make sure it is not cached if the cache middleware is active.

If the page is cacheable, but you still want the permission check to be
performed, you can pass a `cacheable=True` argument to
`AdminSite.admin_view()`:

```
path('my_view/', self.admin_site.admin_view(self.my_view, cacheable=True))
```

`ModelAdmin` views have `model_admin` attributes. Other
`AdminSite` views have `admin_site` attributes.

#### `ModelAdmin.get_form(request, obj=None, **kwargs)`

admin の追加と変更のビューで使うための [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) クラスを返します。[`add_view()`](#django.contrib.admin.ModelAdmin.add_view) と [`change_view()`](#django.contrib.admin.ModelAdmin.change_view) を参照してください。

基本の実装は [`modelform_factory()`](/ja/2.2/ref/forms/models/#django.forms.models.modelform_factory) を使用して [`form`](#django.contrib.admin.ModelAdmin.form) をサブクラス化し、[`fields`](#django.contrib.admin.ModelAdmin.fields) や [`exclude`](#django.contrib.admin.ModelAdmin.exclude) といった属性によって修正されます。なので、例えばスーパーユーザーに対して追加的なフィールドを与えたい場合は、以下のように基本のフォームを変更することができます:

```
class MyModelAdmin(admin.ModelAdmin):
    def get_form(self, request, obj=None, **kwargs):
        if request.user.is_superuser:
            kwargs['form'] = MySuperuserForm
        return super().get_form(request, obj, **kwargs)
```

シンプルに [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) クラスを直接返すこともできます。

#### `ModelAdmin.get_formsets_with_inlines(request, obj=None)`

admin の追加や変更のビューで使用するための (`FormSet`, [`InlineModelAdmin`](#django.contrib.admin.InlineModelAdmin)) ペアを生成します。

例えば、変更ビューのみで特定のインラインを表示したい場合、以下のように `get_formsets_with_inlines` をオーバーライドできます:

```
class MyModelAdmin(admin.ModelAdmin):
    inlines = [MyInline, SomeOtherInline]

    def get_formsets_with_inlines(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if not isinstance(inline, MyInline) or obj is not None:
                yield inline.get_formset(request, obj), inline
```

#### `ModelAdmin.formfield_for_foreignkey(db_field, request, **kwargs)`

`ModelAdmin` の `formfield_for_foreignkey` を使うと、ForignKey フィールドに対するデフォルトのフォームフィールドをオーバーライドできます。例えば、ユーザーに基づいてこの ForeignKey フィールドに対するオブジェクトのサブセットを返すには:

```
class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == "car":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_foreignkey(db_field, request, **kwargs)
```

これは、`HttpRequest` インスタンスを使って `Car` ForeignKey フィールドをフィルタし、特定の `User` インスタンスが所有する car のみを表示します。

#### `ModelAdmin.formfield_for_manytomany(db_field, request, **kwargs)`

`formfield_for_foreignkey` メソッドと同じように、`formfield_for_manytomany` メソッドをオーバーライドすると ManyToMany に対するデフォルトのフォームフィールドを変更できます。 例えば、あるオーナーは複数の car を所有でき、また car は複数のオーナーに所有されるとすると -- 多対多の関係です --`Car` のフィールドをフィルタして特定の `User` が所有する car だけを表示できます:

```
class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_manytomany(self, db_field, request, **kwargs):
        if db_field.name == "cars":
            kwargs["queryset"] = Car.objects.filter(owner=request.user)
        return super().formfield_for_manytomany(db_field, request, **kwargs)
```

#### `ModelAdmin.formfield_for_choice_field(db_field, request, **kwargs)`

`formfield_for_foreignkey` や `formfield_for_manytomany` メソッドと同じように、`formfield_for_choice_field` メソッドをオーバーライドすると選択肢として宣言されたフィールドに対するデフォルトのフォームフィールドを変更できます。 例えば、スーパーユーザーと通常のスタッフで表示する選択肢を違うものにしたい場合、以下のように記述できます:

```
class MyModelAdmin(admin.ModelAdmin):
    def formfield_for_choice_field(self, db_field, request, **kwargs):
        if db_field.name == "status":
            kwargs['choices'] = (
                ('accepted', 'Accepted'),
                ('denied', 'Denied'),
            )
            if request.user.is_superuser:
                kwargs['choices'] += (('ready', 'Ready for deployment'),)
        return super().formfield_for_choice_field(db_field, request, **kwargs)
```

> **ノート**
>
> フォームフィールドにセットされたすべての `choices` 属性はそのフォームのフィールドのみに制限されます。モデル上の一致するフィールドに選択肢がセットされている場合、フォームに提供される選択肢はこの選択肢の有効なサブセットでなくてはなりません。そうでない場合、フォームの送信は、モデル自身の保存前のバリデーションで [`ValidationError`](/ja/2.2/ref/exceptions/#django.core.exceptions.ValidationError) とともに失敗します。

#### `ModelAdmin.get_changelist(request, **kwargs)`

リスト作成に使われる ```Changelist``を返します。デフォルトでは、``django.contrib.admin.views.main.ChangeList``` が使われます。このクラスを継承することで、リスト作成の挙動を変更することができます。

#### `ModelAdmin.get_changelist_form(request, **kwargs)`

チェンジリストページの `Formset` で使うための [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) クラスを返します。カスタムフォームを使うには、例えば:

```
from django import forms

class MyForm(forms.ModelForm):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_form(self, request, **kwargs):
        return MyForm
```

> **ノート**
>
> [`ModelForm`](/ja/2.2/topics/forms/modelforms/#django.forms.ModelForm) で `Meta.model` 属性を定義した場合、`Meta.fields` 属性 (ないし `Meta.exclude` 属性) も定義する必要があります。しかし\`\`ModelAdmin\`\` はこの値を無視して、[`ModelAdmin.list_editable`](#django.contrib.admin.ModelAdmin.list_editable) 属性をオーバーライドします。最も簡単な解決方法は、`Meta.model` 属性を除外することです。これは `ModelAdmin` が使用する正しいモデルを提供するからです。

#### `ModelAdmin.get_changelist_formset(request, **kwargs)`

[`list_editable`](#django.contrib.admin.ModelAdmin.list_editable) を使っている場合、チェンジリストページで使用するための [ModelFormSet](/ja/2.2/topics/forms/modelforms/#model-formsets) クラスを返します。カスタムのフォームセットを使うには、例えば:

```
from django.forms import BaseModelFormSet

class MyAdminFormSet(BaseModelFormSet):
    pass

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_formset(self, request, **kwargs):
        kwargs['formset'] = MyAdminFormSet
        return super().get_changelist_formset(request, **kwargs)
```

#### `ModelAdmin.lookup_allowed(lookup, value)`

The objects in the changelist page can be filtered with lookups from the
URL's query string. This is how [`list_filter`](#django.contrib.admin.ModelAdmin.list_filter) works, for example. The
lookups are similar to what's used in [`QuerySet.filter()`](/ja/2.2/ref/models/querysets/#django.db.models.query.QuerySet.filter) (e.g.
`user__email=user@example.com`). Since the lookups in the query string
can be manipulated by the user, they must be sanitized to prevent
unauthorized data exposure.

The `lookup_allowed()` method is given a lookup path from the query string
(e.g. `'user__email'`) and the corresponding value
(e.g. `'user@example.com'`), and returns a boolean indicating whether
filtering the changelist's `QuerySet` using the parameters is permitted.
If `lookup_allowed()` returns `False`, `DisallowedModelAdminLookup`
(subclass of [`SuspiciousOperation`](/ja/2.2/ref/exceptions/#django.core.exceptions.SuspiciousOperation)) is raised.

By default, `lookup_allowed()` allows access to a model's local fields,
field paths used in [`list_filter`](#django.contrib.admin.ModelAdmin.list_filter) (but not paths from
[`get_list_filter()`](#django.contrib.admin.ModelAdmin.get_list_filter)), and lookups required for
[`limit_choices_to`](/ja/2.2/ref/models/fields/#django.db.models.ForeignKey.limit_choices_to) to function
correctly in [`raw_id_fields`](#django.contrib.admin.ModelAdmin.raw_id_fields).

Override this method to customize the lookups permitted for your
[`ModelAdmin`](#django.contrib.admin.ModelAdmin) subclass.

#### `ModelAdmin.has_view_permission(request, obj=None)`

> **New in Django 2.1**

`obj` の閲覧が許可されている場合は `True` を、そうでなければ `False` を返します。obj が `None` の場合、この種類のオブジェクトの閲覧が一般的に許可されているかどうかを表すよう、`True` か `False` を指定します (例えば、`False` は現在のユーザーがこの種類のすべてのオブジェクトを閲覧できないことを意味します)。

デフォルトの実装では、ユーザーが "change" か "view" 権限を持っていれば `True` を返します。

#### `ModelAdmin.has_add_permission(request)`

オブジェクトの追加が許可されていれば `True` を、そうでなければ `False` を返します。

#### `ModelAdmin.has_change_permission(request, obj=None)`

`obj` の編集が許可されている場合は `True` を、そうでなければ `False` を返します。`obj` が `None` の場合、この種類のオブジェクトの編集が一般的に許可されているかどうかを表すよう、`True` か `False` を指定します (例えば、`False` は現在のユーザーがこの種類のすべてのオブジェクトを編集できないことを意味します)。

#### `ModelAdmin.has_delete_permission(request, obj=None)`

`obj` の削除が許可されている場合は `True` を、そうでなければ `False` を返します。`obj` が `None` の場合、この種類のオブジェクトの削除が一般的に許可されているかどうかを表すよう、`True` か `False` を指定します (例えば、`False` は現在のユーザーがこの種類のすべてのオブジェクトを削除できないことを意味します)。

#### `ModelAdmin.has_module_permission(request)`

admin のインデックスページでモジュールを表示し、そのモジュールへのアクセスを許可する場合は `True` を、そうでなければ `False` を返します。デフォルトでは [`User.has_module_perms()`](/ja/2.2/ref/contrib/auth/#django.contrib.auth.models.User.has_module_perms) を使用します。 オーバーライドしても閲覧、追加、変更、削除のアクセス権は制限しません。アクセス権の制限には [`has_view_permission()`](#django.contrib.admin.ModelAdmin.has_view_permission)、[`has_add_permission()`](#django.contrib.admin.ModelAdmin.has_add_permission)、[`has_change_permission()`](#django.contrib.admin.ModelAdmin.has_change_permission)、[`has_delete_permission()`](#django.contrib.admin.ModelAdmin.has_delete_permission) を使用してください。

#### `ModelAdmin.get_queryset(request)`

`ModelAdmin` の `get_queryset` メソッドは admin サイトで編集可能なモデルインスタンスのすべての [`QuerySet`](/ja/2.2/ref/models/querysets/#django.db.models.query.QuerySet) を返します。このメソッドをオーバーライドする場面の 1 つは、ログイン中のユーザーが所有するオブジェクトを表示することです:

```
class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = super().get_queryset(request)
        if request.user.is_superuser:
            return qs
        return qs.filter(author=request.user)
```

#### `ModelAdmin.message_user(request, message, level=messages.INFO, extra_tags='', fail_silently=False)`

[`django.contrib.messages`](/ja/2.2/ref/contrib/messages/#module-django.contrib.messages) バックエンドを使ってユーザーにメッセージを送ります。[custom ModelAdmin example](/ja/2.2/ref/contrib/admin/actions/#custom-admin-action) を参照してください。

Keyword arguments allow you to change the message level, add extra CSS
tags, or fail silently if the `contrib.messages` framework is not
installed. These keyword arguments match those for
[`django.contrib.messages.add_message()`](/ja/2.2/ref/contrib/messages/#django.contrib.messages.add_message), see that function's
documentation for more details. One difference is that the level may be
passed as a string label in addition to integer/constant.

#### `ModelAdmin.get_paginator(request, queryset, per_page, orphans=0, allow_empty_first_page=True)`

ビューに対して使う paginator to のインスタンスを返します。デフォルトでは、[`paginator`](#django.contrib.admin.ModelAdmin.paginator) のインスタンスを継承します。

#### `ModelAdmin.response_add(request, obj, post_url_continue=None)`

[`add_view()`](#django.contrib.admin.ModelAdmin.add_view) ステージに対する [`HttpResponse`](/ja/2.2/ref/request-response/#django.http.HttpResponse) を決定します。

`response_add` は、admin フォームが送信され、オブジェクトとすべての関係インスタンスが作成および保存された直後に呼び出されます。オーバーライドすることで、オブジェクトが作成された後のデフォルトの挙動を変更することができます。

#### `ModelAdmin.response_change(request, obj)`

[`change_view()`](#django.contrib.admin.ModelAdmin.change_view) ステージに対する [`HttpResponse`](/ja/2.2/ref/request-response/#django.http.HttpResponse) を決定します。

`response_change` は、admin フォームが送信され、オブジェクトとすべての関係インスタンスが保存された直後に呼び出されます。オーバーライドすることで、オブジェクトが変更された後のデフォルトの挙動を変更することができます。

#### `ModelAdmin.response_delete(request, obj_display, obj_id)`

[`delete_view()`](#django.contrib.admin.ModelAdmin.delete_view) ステージに対する [`HttpResponse`](/ja/2.2/ref/request-response/#django.http.HttpResponse) を決定します。

`response_delete` は、オブジェクトが削除された後に呼び出されます。オーバーライドすることで、オブジェクトが削除された後のデフォルトの挙動を変更することができます。

obj\_display\`\`は削除されたオブジェクトの名前を表す文字列です。

`obj_id` is the serialized identifier used to retrieve the object to be
deleted.

#### `ModelAdmin.get_changeform_initial_data(request)`

admin の変更フォームの初期データに対するフックです。デフォルトでは、フィールドには `GET` パラメータで初期値が与えられます。例えば、`?name=initial_value` は\`\`name\`\` フィールドの初期値を `initial_value` にセットします。

このメソッドは、`{'fieldname': 'fieldval'}` という形式のディクショナリを返します:

```
def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}
```

#### `ModelAdmin.get_deleted_objects(objs, request)`

> **New in Django 2.1**

A hook for customizing the deletion process of the [`delete_view()`](#django.contrib.admin.ModelAdmin.delete_view) and
the "delete selected" [action](/ja/2.2/ref/contrib/admin/actions/).

The `objs` argument is a homogeneous iterable of objects (a `QuerySet`
or a list of model instances) to be deleted, and `request` is the
[`HttpRequest`](/ja/2.2/ref/request-response/#django.http.HttpRequest).

This method must return a 4-tuple of
`(deleted_objects, model_count, perms_needed, protected)`.

`deleted_objects` is a list of strings representing all the objects that
will be deleted. If there are any related objects to be deleted, the list
is nested and includes those related objects. The list is formatted in the
template using the [`unordered_list`](/ja/2.2/ref/templates/builtins/#std-templatefilter-unordered_list) filter.

`model_count` is a dictionary mapping each model's
[`verbose_name_plural`](/ja/2.2/ref/models/options/#django.db.models.Options.verbose_name_plural) to the number of
objects that will be deleted.

`perms_needed` is a set of [`verbose_name`](/ja/2.2/ref/models/options/#django.db.models.Options.verbose_name)s
of the models that the user doesn't have permission to delete.

`protected` is a list of strings representing of all the protected
related objects that can't be deleted. The list is displayed in the
template.

#### その他のメソッド

#### `ModelAdmin.add_view(request, form_url='', extra_context=None)`

モデルインスタンスの追加ページに対する Django のビューです。以下のノートをご覧ください。

#### `ModelAdmin.change_view(request, object_id, form_url='', extra_context=None)`

モデルインスタンスの編集ページに対する Django のビューです。以下のノートをご覧ください。

#### `ModelAdmin.changelist_view(request, extra_context=None)`

モデルインスタンスの変更リストおよびアクションページに対する Django のビューです。以下のノートをご覧ください。

#### `ModelAdmin.delete_view(request, object_id, extra_context=None)`

モデルインスタンスの削除の確認ページに対する Django のビューです。以下のノートをご覧ください。

#### `ModelAdmin.history_view(request, object_id, extra_context=None)`

与えられたモデルのインスタンスに対する修正履歴を表示するページに対する Django のビューです。

Unlike the hook-type `ModelAdmin` methods detailed in the previous section,
these five methods are in reality designed to be invoked as Django views from
the admin application URL dispatching handler to render the pages that deal
with model instances CRUD operations. As a result, completely overriding these
methods will significantly change the behavior of the admin application.

One common reason for overriding these methods is to augment the context data
that is provided to the template that renders the view. In the following
example, the change view is overridden so that the rendered template is
provided some extra mapping data that would not otherwise be available:

```
class MyModelAdmin(admin.ModelAdmin):

    # A template for a very customized change view:
    change_form_template = 'admin/myapp/extras/openstreetmap_change_form.html'

    def get_osm_info(self):
        # ...
        pass

    def change_view(self, request, object_id, form_url='', extra_context=None):
        extra_context = extra_context or {}
        extra_context['osm_data'] = self.get_osm_info()
        return super().change_view(
            request, object_id, form_url, extra_context=extra_context,
        )
```

These views return [`TemplateResponse`](/ja/2.2/ref/template-response/#django.template.response.TemplateResponse)
instances which allow you to easily customize the response data before
rendering. For more details, see the [TemplateResponse documentation](/ja/2.2/ref/template-response/).

### `ModelAdmin` アセットの定義

ビューを追加したり変更したりするために、CSS や JavaScript を追加したいことがあるかもしれません。そういうときには `ModelAdmin` の `Media` インナークラスを使用します:

```
class ArticleAdmin(admin.ModelAdmin):
    class Media:
        css = {
            "all": ("my_styles.css",)
        }
        js = ("my_code.js",)
```

[staticfiles app](/ja/2.2/ref/contrib/staticfiles/) は、すべてのアセットのパスに [`STATIC_URL`](/ja/2.2/ref/settings/#std-setting-STATIC_URL) ([`STATIC_URL`](/ja/2.2/ref/settings/#std-setting-STATIC_URL) が `None` の場合は [`MEDIA_URL`](/ja/2.2/ref/settings/#std-setting-MEDIA_URL)) を prepend します。[regular asset definitions on forms](/ja/2.2/topics/forms/media/#form-asset-paths) と同じルールが適用されます。

#### jQuery

Django admin の JavaScript は [jQuery](https://jquery.com) ライブラリを使用します。

ユーザーのスクリプトやライブラリとの競合を避けるため、Django の jQuery (version 3.3.1) は `django.jQuery` という名前空間にあります。jQuery を自身の admin の JavaScript で使うとき、別途ライブラリを準備しないで、チェンジリストや追加、編集ビュー上で `django.jQuery` オブジェクトを使うことができます。

> **Changed in Django 2.1**
>
> jQuery が 2.2.3 から 3.3.1 にアップグレードしました。

> **Changed in Django 2.2.13**
>
> jQuery was upgraded from 3.3.1 to 3.5.1.

[`ModelAdmin`](#django.contrib.admin.ModelAdmin) クラスはデフォルトで jQuery を要件とするので、特別なニーズがない限り jQuery をメディアリソースの `ModelAdmin` のリストに追加する必要はありません。例えば、jQuery ライブラリがグローバルな名前空間を持つ必要がある場合 (例えばサードパーティの jQuery プラグインを使用する場合など)、もしくは jQuery の新しいバージョンを使いたい場合には、自分自身でコピーを用意する必要があります。

Django には、非圧縮と 'minified' のバージョンのjQuery があり、それぞれ `jquery.js` と\`\`jquery.min.js\`\` となっています。

[`ModelAdmin`](#django.contrib.admin.ModelAdmin) and [`InlineModelAdmin`](#django.contrib.admin.InlineModelAdmin) have a `media` property
that returns a list of `Media` objects which store paths to the JavaScript
files for the forms and/or formsets. If [`DEBUG`](/ja/2.2/ref/settings/#std-setting-DEBUG) is `True` it will
return the uncompressed versions of the various JavaScript files, including
`jquery.js`; if not, it will return the 'minified' versions.

### カスタムのバリデーションを admin に追加する

Adding custom validation of data in the admin is quite easy. The automatic
admin interface reuses [`django.forms`](/ja/2.2/ref/forms/api/#module-django.forms), and the `ModelAdmin` class gives
you the ability define your own form:

```
class ArticleAdmin(admin.ModelAdmin):
    form = MyArticleAdminForm
```

`MyArticleAdminForm` can be defined anywhere as long as you import where
needed. Now within your form you can add your own custom validation for
any field:

```
class MyArticleAdminForm(forms.ModelForm):
    def clean_name(self):
        # do something that validates your data
        return self.cleaned_data["name"]
```

It is important you use a `ModelForm` here otherwise things can break. See
the [forms](/ja/2.2/ref/forms/) documentation on [custom validation](/ja/2.2/ref/forms/validation/) and, more specifically, the
[model form validation notes](/ja/2.2/topics/forms/modelforms/#overriding-modelform-clean-method) for more
information.

## `InlineModelAdmin` オブジェクト

#### `class InlineModelAdmin`

#### `class TabularInline`

#### `class StackedInline`

admin インターフェースには、親モデルと同じページでモデルを編集する機能があります。この機能をインラインと呼びます。以下の 2 つのモデルがあるとしましょう:

```
from django.db import models

class Author(models.Model):
   name = models.CharField(max_length=100)

class Book(models.Model):
   author = models.ForeignKey(Author, on_delete=models.CASCADE)
   title = models.CharField(max_length=100)
```

author のページで、author が書いた book を編集することができます。`ModelAdmin.inlines` 内でモデルに対するインラインを追加します:

```
from django.contrib import admin

class BookInline(admin.TabularInline):
    model = Book

class AuthorAdmin(admin.ModelAdmin):
    inlines = [
        BookInline,
    ]
```

Django には、以下の通り `InlineModelAdmin` のサブクラスが 2 つあります:

- [`TabularInline`](#django.contrib.admin.TabularInline)
- [`StackedInline`](#django.contrib.admin.StackedInline)

この 2 つの違いは、単に描画するために使われるテンプレートの違いです。

### `InlineModelAdmin` のオプション

`InlineModelAdmin` は `ModelAdmin` と多くの機能を共有しており、さらにいくつかの独自の機能を有しています (共有の機能は実際には `BaseModelAdmin` スーパークラスで定義されています)。共有の機能は:

- [`form`](#django.contrib.admin.InlineModelAdmin.form)
- [`fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets)
- [`fields`](#django.contrib.admin.ModelAdmin.fields)
- [`formfield_overrides`](#django.contrib.admin.ModelAdmin.formfield_overrides)
- [`exclude`](#django.contrib.admin.ModelAdmin.exclude)
- [`filter_horizontal`](#django.contrib.admin.ModelAdmin.filter_horizontal)
- [`filter_vertical`](#django.contrib.admin.ModelAdmin.filter_vertical)
- [`ordering`](#django.contrib.admin.ModelAdmin.ordering)
- [`prepopulated_fields`](#django.contrib.admin.ModelAdmin.prepopulated_fields)
- [`get_fieldsets()`](#django.contrib.admin.ModelAdmin.get_fieldsets)
- [`get_queryset()`](#django.contrib.admin.ModelAdmin.get_queryset)
- [`radio_fields`](#django.contrib.admin.ModelAdmin.radio_fields)
- [`readonly_fields`](#django.contrib.admin.ModelAdmin.readonly_fields)
- [`raw_id_fields`](#django.contrib.admin.InlineModelAdmin.raw_id_fields)
- [`formfield_for_choice_field()`](#django.contrib.admin.ModelAdmin.formfield_for_choice_field)
- [`formfield_for_foreignkey()`](#django.contrib.admin.ModelAdmin.formfield_for_foreignkey)
- [`formfield_for_manytomany()`](#django.contrib.admin.ModelAdmin.formfield_for_manytomany)
- [`has_module_permission()`](#django.contrib.admin.ModelAdmin.has_module_permission)

`InlineModelAdmin` クラスは、以下を追加またはカスタマイズしています:

#### `InlineModelAdmin.model`

院来駕使用するモデル。これは必須です。

#### `InlineModelAdmin.fk_name`

モデルの外部キーの名前です。多くの場合、これは自動的に処理されますが、同じ親モデルに対して複数の外部キーがある場合には `fk_name` を明示的に指定する必要があります。

#### `InlineModelAdmin.formset`

これはデフォルトでは [`BaseInlineFormSet`](/ja/2.2/topics/forms/modelforms/#django.forms.models.BaseInlineFormSet) です。自分自身のフォームセットを使用すると、カスタマイズの幅が広がります。インラインは [model formsets](/ja/2.2/topics/forms/modelforms/#model-formsets) にて構築されます。

#### `InlineModelAdmin.form`

`form` に対する値で、デフォルトは `ModelForm` です。これは、このインラインに対してフォームセットが生成される際に [`inlineformset_factory()`](/ja/2.2/ref/forms/models/#django.forms.models.inlineformset_factory) に渡されるものです。

> **Warning**
>
> When writing custom validation for `InlineModelAdmin` forms, be cautious
> of writing validation that relies on features of the parent model. If the
> parent model fails to validate, it may be left in an inconsistent state as
> described in the warning in [ModelForm の検証 (バリデーション)](/ja/2.2/topics/forms/modelforms/#validation-on-modelform).

#### `InlineModelAdmin.classes`

インラインに対して描画するフォームセットに適用する、追加的な CSS クラスのリストないしタプルです。デフォルトは `None` です。[`fieldsets`](#django.contrib.admin.ModelAdmin.fieldsets) で設定したクラスと同様に、`collapse` クラスを伴うインラインは最初は折りたたまれており小さな "show" リンクを持ちます。

#### `InlineModelAdmin.extra`

フォームセットが初期のフォームに加えて表示する追加的なフォームの数をコントロールします。詳しくは [formsets documentation](/ja/2.2/topics/forms/formsets/) を参照してください。

JavaScript が有効なブラウザを使っているユーザーに対しては、"1 つ追加" のリンクが提供され、`extra` 引数の結果提供されるインラインに加えていくつでもインラインを追加することができます。

The dynamic link will not appear if the number of currently displayed forms
exceeds `max_num`, or if the user does not have JavaScript enabled.

[`InlineModelAdmin.get_extra()`](#django.contrib.admin.InlineModelAdmin.get_extra) でも追加フォームの数をカスタマイズできます。

#### `InlineModelAdmin.max_num`

インラインに表示するフォームの最大数をコントロールします。オブジェクトの買うと直接関係はありませんが、値が小さい場合には関係する可能性があります。詳しくは [Limiting the number of editable objects](/ja/2.2/topics/forms/modelforms/#model-formsets-max-num) を参照してください。

[`InlineModelAdmin.get_max_num()`](#django.contrib.admin.InlineModelAdmin.get_max_num) でも追加フォームの最大数をカスタマイズできます。

#### `InlineModelAdmin.min_num`

インラインに表示するフォームの最小数をコントロールします。詳しくは [`modelformset_factory()`](/ja/2.2/ref/forms/models/#django.forms.models.modelformset_factory) を参照してください。

[`InlineModelAdmin.get_min_num()`](#django.contrib.admin.InlineModelAdmin.get_min_num) でも追加フォームの最小数をカスタマイズできます。

#### `InlineModelAdmin.raw_id_fields`

デフォルトでは、`ForeignKey` のフィールドに対して Django の admin はセレクトボックスのインターフェース (`<select>`) を使用します。ドロップダウン内に表示する関係インスタンスをすべて選択するオーバーヘッドから逃れたいこともあるでしょう。

`raw_id_fields` は、`ForeignKey` や `ManyToManyField` に対する `Input` ウィジェットを適用したいフィールドのリストです:

```
class BookInline(admin.TabularInline):
    model = Book
    raw_id_fields = ("pages",)
```

#### `InlineModelAdmin.template`

ページ上でインラインを描画するのに使われるテンプレートです。

#### `InlineModelAdmin.verbose_name`

モデルのインナー `Meta` クラス内で見つかった `verbose_name` のオーバーライドです。

#### `InlineModelAdmin.verbose_name_plural`

モデルのインナー `Meta` クラス内で見つかった `verbose_name_plural` のオーバーライドです。

#### `InlineModelAdmin.can_delete`

インライン内でインラインオブジェクトを削除可能にするかどうかを指定します。デフォルトは `True` です。

#### `InlineModelAdmin.show_change_link`

admin 内で変更可能なインラインオブジェクトをが変更フォームへのリンクを持つかどうかを指定します。デフォルトは `False` です。

#### `InlineModelAdmin.get_formset(request, obj=None, **kwargs)`

Returns a [`BaseInlineFormSet`](/ja/2.2/topics/forms/modelforms/#django.forms.models.BaseInlineFormSet) class for use in
admin add/change views. `obj` is the parent object being edited or
`None` when adding a new parent. See the example for
[`ModelAdmin.get_formsets_with_inlines`](#django.contrib.admin.ModelAdmin.get_formsets_with_inlines).

#### `InlineModelAdmin.get_extra(request, obj=None, **kwargs)`

使用する追加インラインフォームの数を返します。デフォルトでは、[`InlineModelAdmin.extra`](#django.contrib.admin.InlineModelAdmin.extra) 属性を返します。

プログラムに従って追加インラインフォームの数を決めたい場合、このメソッドをオーバーライドしてください。例えば、モデルインスタンス (キーワード引数の `obj` で渡されています) に基づいて数を決められます:

```
class BinaryTreeAdmin(admin.TabularInline):
    model = BinaryTree

    def get_extra(self, request, obj=None, **kwargs):
        extra = 2
        if obj:
            return extra - obj.binarytree_set.count()
        return extra
```

#### `InlineModelAdmin.get_max_num(request, obj=None, **kwargs)`

使用する追加インラインフォームの最大数を返します。デフォルトでは、[`InlineModelAdmin.max_num`](#django.contrib.admin.InlineModelAdmin.max_num) 属性を返します。

プログラムに従ってインラインフォームの最大数を決めたい場合、このメソッドをオーバーライドしてください。例えば、モデルインスタンス (キーワード引数の `obj` で渡されています) に基づいて最大数を決められます:

```
class BinaryTreeAdmin(admin.TabularInline):
    model = BinaryTree

    def get_max_num(self, request, obj=None, **kwargs):
        max_num = 10
        if obj and obj.parent:
            return max_num - 5
        return max_num
```

#### `InlineModelAdmin.get_min_num(request, obj=None, **kwargs)`

使用する追加インラインフォームの最小数を返します。デフォルトでは、[`InlineModelAdmin.min_num`](#django.contrib.admin.InlineModelAdmin.min_num) 属性を返します。

プログラムに従ってインラインフォームの最小数を決めたい場合、このメソッドをオーバーライドしてください。例えば、モデルインスタンス (キーワード引数の `obj` で渡されています) に基づいて最小数を決められます:

#### `InlineModelAdmin.has_add_permission(request, obj)`

インラインオブジェクトの追加が許可されている場合 `True` を、そうでなければ `False` を返します。`obj` は編集される親オブジェクトか、新規追加の場合には `None` となります。

> **Changed in Django 2.1**
>
> The `obj` argument was added. During the deprecation period, it may
> also be `None` if third-party calls to `has_add_permission()` don't
> provide it.

#### `InlineModelAdmin.has_change_permission(request, obj=None)`

インラインオブジェクトの編集が許可されている場合 `True` を、そうでなければ `False` を返します。`obj` は編集される親オブジェクトです。

#### `InlineModelAdmin.has_delete_permission(request, obj=None)`

インラインオブジェクトの削除が許可されている場合 `True` を、そうでなければ `False` を返します。`obj` は編集される親オブジェクトです。

> **Note**
>
> The `obj` argument passed to `InlineModelAdmin` methods is the parent
> object being edited or `None` when adding a new parent.

### 同じ親モデルへの複数の外部キーを持つモデルを扱う

同じモデルに対する複数の外部キーを持つこともあり得ます。例として以下のモデルを見てみましょう:

```
from django.db import models

class Friendship(models.Model):
    to_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="friends")
    from_person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name="from_friends")
```

`Person` の admin の追加や変更ページでインラインを表示したい場合は、自動的に判別することができないため、外部キーを明示的に定義する必要があります:

```
from django.contrib import admin
from myapp.models import Friendship

class FriendshipInline(admin.TabularInline):
    model = Friendship
    fk_name = "to_person"

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        FriendshipInline,
    ]
```

### 多対多のモデルを扱う

By default, admin widgets for many-to-many relations will be displayed
on whichever model contains the actual reference to the
[`ManyToManyField`](/ja/2.2/ref/models/fields/#django.db.models.ManyToManyField). Depending on your `ModelAdmin`
definition, each many-to-many field in your model will be represented by a
standard HTML `<select multiple>`, a horizontal or vertical filter, or a
`raw_id_admin` widget. However, it is also possible to replace these
widgets with inlines.

Suppose we have the following models:

```
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, related_name='groups')
```

If you want to display many-to-many relations using an inline, you can do
so by defining an `InlineModelAdmin` object for the relationship:

```
from django.contrib import admin

class MembershipInline(admin.TabularInline):
    model = Group.members.through

class PersonAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]

class GroupAdmin(admin.ModelAdmin):
    inlines = [
        MembershipInline,
    ]
    exclude = ('members',)
```

There are two features worth noting in this example.

Firstly - the `MembershipInline` class references `Group.members.through`.
The `through` attribute is a reference to the model that manages the
many-to-many relation. This model is automatically created by Django when you
define a many-to-many field.

Secondly, the `GroupAdmin` must manually exclude the `members` field.
Django displays an admin widget for a many-to-many field on the model that
defines the relation (in this case, `Group`). If you want to use an inline
model to represent the many-to-many relationship, you must tell Django's admin
to *not* display this widget - otherwise you will end up with two widgets on
your admin page for managing the relation.

Note that when using this technique the
[`m2m_changed`](/ja/2.2/ref/signals/#django.db.models.signals.m2m_changed) signals aren't triggered. This
is because as far as the admin is concerned, `through` is just a model with
two foreign key fields rather than a many-to-many relation.

In all other respects, the `InlineModelAdmin` is exactly the same as any
other. You can customize the appearance using any of the normal
`ModelAdmin` properties.

### Working with many-to-many intermediary models

When you specify an intermediary model using the `through` argument to a
[`ManyToManyField`](/ja/2.2/ref/models/fields/#django.db.models.ManyToManyField), the admin will not display a
widget by default. This is because each instance of that intermediary model
requires more information than could be displayed in a single widget, and the
layout required for multiple widgets will vary depending on the intermediate
model.

However, we still want to be able to edit that information inline. Fortunately,
this is easy to do with inline admin models. Suppose we have the following
models:

```
from django.db import models

class Person(models.Model):
    name = models.CharField(max_length=128)

class Group(models.Model):
    name = models.CharField(max_length=128)
    members = models.ManyToManyField(Person, through='Membership')

class Membership(models.Model):
    person = models.ForeignKey(Person, on_delete=models.CASCADE)
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    date_joined = models.DateField()
    invite_reason = models.CharField(max_length=64)
```

The first step in displaying this intermediate model in the admin is to
define an inline class for the `Membership` model:

```
class MembershipInline(admin.TabularInline):
    model = Membership
    extra = 1
```

This simple example uses the default `InlineModelAdmin` values for the
`Membership` model, and limits the extra add forms to one. This could be
customized using any of the options available to `InlineModelAdmin` classes.

Now create admin views for the `Person` and `Group` models:

```
class PersonAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class GroupAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)
```

Finally, register your `Person` and `Group` models with the admin site:

```
admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)
```

Now your admin site is set up to edit `Membership` objects inline from
either the `Person` or the `Group` detail pages.

### Using generic relations as an inline

It is possible to use an inline with generically related objects. Let's say
you have the following models:

```
from django.contrib.contenttypes.fields import GenericForeignKey
from django.db import models

class Image(models.Model):
    image = models.ImageField(upload_to="images")
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey("content_type", "object_id")

class Product(models.Model):
    name = models.CharField(max_length=100)
```

If you want to allow editing and creating an `Image` instance on the
`Product`, add/change views you can use
[`GenericTabularInline`](/ja/2.2/ref/contrib/contenttypes/#django.contrib.contenttypes.admin.GenericTabularInline)
or [`GenericStackedInline`](/ja/2.2/ref/contrib/contenttypes/#django.contrib.contenttypes.admin.GenericStackedInline) (both
subclasses of [`GenericInlineModelAdmin`](/ja/2.2/ref/contrib/contenttypes/#django.contrib.contenttypes.admin.GenericInlineModelAdmin))
provided by [`admin`](/ja/2.2/ref/contrib/contenttypes/#module-django.contrib.contenttypes.admin). They implement tabular
and stacked visual layouts for the forms representing the inline objects,
respectively, just like their non-generic counterparts. They behave just like
any other inline. In your `admin.py` for this example app:

```
from django.contrib import admin
from django.contrib.contenttypes.admin import GenericTabularInline

from myproject.myapp.models import Image, Product

class ImageInline(GenericTabularInline):
    model = Image

class ProductAdmin(admin.ModelAdmin):
    inlines = [
        ImageInline,
    ]

admin.site.register(Product, ProductAdmin)
```

See the [contenttypes documentation](/ja/2.2/ref/contrib/contenttypes/) for more
specific information.

## Overriding admin templates

It is relatively easy to override many of the templates which the admin module
uses to generate the various pages of an admin site. You can even override a
few of these templates for a specific app, or a specific model.

### Set up your projects admin template directories

The admin template files are located in the `contrib/admin/templates/admin`
directory.

In order to override one or more of them, first create an `admin` directory
in your project's `templates` directory. This can be any of the directories
you specified in the [`DIRS`](/ja/2.2/ref/settings/#std-setting-TEMPLATES-DIRS) option of the
`DjangoTemplates` backend in the [`TEMPLATES`](/ja/2.2/ref/settings/#std-setting-TEMPLATES) setting. If you have
customized the `'loaders'` option, be sure
`'django.template.loaders.filesystem.Loader'` appears before
`'django.template.loaders.app_directories.Loader'` so that your custom
templates will be found by the template loading system before those that are
included with [`django.contrib.admin`](#module-django.contrib.admin).

Within this `admin` directory, create sub-directories named after your app.
Within these app subdirectories create sub-directories named after your models.
Note, that the admin app will lowercase the model name when looking for the
directory, so make sure you name the directory in all lowercase if you are
going to run your app on a case-sensitive filesystem.

To override an admin template for a specific app, copy and edit the template
from the `django/contrib/admin/templates/admin` directory, and save it to one
of the directories you just created.

For example, if we wanted to add a tool to the change list view for all the
models in an app named `my_app`, we would copy
`contrib/admin/templates/admin/change_list.html` to the
`templates/admin/my_app/` directory of our project, and make any necessary
changes.

If we wanted to add a tool to the change list view for only a specific model
named 'Page', we would copy that same file to the
`templates/admin/my_app/page` directory of our project.

### Overriding vs. replacing an admin template

Because of the modular design of the admin templates, it is usually neither
necessary nor advisable to replace an entire template. It is almost always
better to override only the section of the template which you need to change.

To continue the example above, we want to add a new link next to the
`History` tool for the `Page` model. After looking at `change_form.html`
we determine that we only need to override the `object-tools-items` block.
Therefore here is our new `change_form.html` :

```html+django
{% extends "admin/change_form.html" %}
{% load i18n admin_urls %}
{% block object-tools-items %}
    <li>
        <a href="{% url opts|admin_urlname:'history' original.pk|admin_urlquote %}" class="historylink">{% trans "History" %}</a>
    </li>
    <li>
        <a href="mylink/" class="historylink">My Link</a>
    </li>
    {% if has_absolute_url %}
        <li>
            <a href="{% url 'admin:view_on_site' content_type_id original.pk %}" class="viewsitelink">{% trans "View on site" %}</a>
        </li>
    {% endif %}
{% endblock %}
```

And that's it! If we placed this file in the `templates/admin/my_app`
directory, our link would appear on the change form for all models within
my\_app.

### Templates which may be overridden per app or model

Not every template in `contrib/admin/templates/admin` may be overridden per
app or per model. The following can:

- `actions.html`
- `app_index.html`
- `change_form.html`
- `change_form_object_tools.html`
- `change_list.html`
- `change_list_object_tools.html`
- `change_list_results.html`
- `date_hierarchy.html`
- `delete_confirmation.html`
- `object_history.html`
- `pagination.html`
- `popup_response.html`
- `prepopulated_fields_js.html`
- `search_form.html`
- `submit_line.html`

> **Changed in Django 2.1**
>
> The ability to override the `actions.html`, `change_form_object_tools.html`,
> `change_list_object_tools.html`, `change_list_results.html`,
> `date_hierarchy.html`, `pagination.html`, `prepopulated_fields_js.html`,
> `search_form.html`, and `submit_line.html` templates was added.

For those templates that cannot be overridden in this way, you may still
override them for your entire project. Just place the new version in your
`templates/admin` directory. This is particularly useful to create custom 404
and 500 pages.

> **Note**
>
> Some of the admin templates, such as `change_list_results.html` are used
> to render custom inclusion tags. These may be overridden, but in such cases
> you are probably better off creating your own version of the tag in
> question and giving it a different name. That way you can use it
> selectively.

### Root and login templates

If you wish to change the index, login or logout templates, you are better off
creating your own `AdminSite` instance (see below), and changing the
[`AdminSite.index_template`](#django.contrib.admin.AdminSite.index_template) , [`AdminSite.login_template`](#django.contrib.admin.AdminSite.login_template) or
[`AdminSite.logout_template`](#django.contrib.admin.AdminSite.logout_template) properties.

## `AdminSite` objects

#### `class AdminSite(name='admin')`

A Django administrative site is represented by an instance of
`django.contrib.admin.sites.AdminSite`; by default, an instance of
this class is created as `django.contrib.admin.site` and you can
register your models and `ModelAdmin` instances with it.

If you want to customize the default admin site, you can [override it](#overriding-default-admin-site).

When constructing an instance of an `AdminSite`, you can provide
a unique instance name using the `name` argument to the constructor. This
instance name is used to identify the instance, especially when
[reversing admin URLs](#admin-reverse-urls). If no instance name is
provided, a default instance name of `admin` will be used.
See [Customizing the AdminSite class](#customizing-adminsite) for an example of customizing the
[`AdminSite`](#django.contrib.admin.AdminSite) class.

### `AdminSite` の属性

Templates can override or extend base admin templates as described in
[Overriding admin templates](#admin-overriding-templates).

#### `AdminSite.site_header`

The text to put at the top of each admin page, as an `<h1>` (a string).
By default, this is "Django administration".

#### `AdminSite.site_title`

The text to put at the end of each admin page's `<title>` (a string). By
default, this is "Django site admin".

#### `AdminSite.site_url`

The URL for the "View site" link at the top of each admin page. By default,
`site_url` is `/`. Set it to `None` to remove the link.

For sites running on a subpath, the [`each_context()`](#django.contrib.admin.AdminSite.each_context) method checks if
the current request has `request.META['SCRIPT_NAME']` set and uses that
value if `site_url` isn't set to something other than `/`.

#### `AdminSite.index_title`

The text to put at the top of the admin index page (a string). By default,
this is "Site administration".

#### `AdminSite.index_template`

Path to a custom template that will be used by the admin site main index
view.

#### `AdminSite.app_index_template`

Path to a custom template that will be used by the admin site app index view.

#### `AdminSite.empty_value_display`

The string to use for displaying empty values in the admin site's change
list. Defaults to a dash. The value can also be overridden on a per
`ModelAdmin` basis and on a custom field within a `ModelAdmin` by
setting an `empty_value_display` attribute on the field. See
[`ModelAdmin.empty_value_display`](#django.contrib.admin.ModelAdmin.empty_value_display) for examples.

#### `AdminSite.login_template`

Path to a custom template that will be used by the admin site login view.

#### `AdminSite.login_form`

Subclass of [`AuthenticationForm`](/ja/2.2/topics/auth/default/#django.contrib.auth.forms.AuthenticationForm) that
will be used by the admin site login view.

#### `AdminSite.logout_template`

Path to a custom template that will be used by the admin site logout view.

#### `AdminSite.password_change_template`

Path to a custom template that will be used by the admin site password
change view.

#### `AdminSite.password_change_done_template`

Path to a custom template that will be used by the admin site password
change done view.

### `AdminSite` のメソッド

#### `AdminSite.each_context(request)`

Returns a dictionary of variables to put in the template context for
every page in the admin site.

Includes the following variables and values by default:

- `site_header`: [`AdminSite.site_header`](#django.contrib.admin.AdminSite.site_header)
- `site_title`: [`AdminSite.site_title`](#django.contrib.admin.AdminSite.site_title)
- `site_url`: [`AdminSite.site_url`](#django.contrib.admin.AdminSite.site_url)
- `has_permission`: [`AdminSite.has_permission()`](#django.contrib.admin.AdminSite.has_permission)
- `available_apps`: a list of applications from the [application registry](/ja/2.2/ref/applications/) available for the current user. Each entry in the
  list is a dict representing an application with the following keys:

  - `app_label`: the application label
  - `app_url`: the URL of the application index in the admin
  - `has_module_perms`: a boolean indicating if displaying and accessing of
    the module's index page is permitted for the current user
  - `models`: a list of the models available in the application

  Each model is a dict with the following keys:

  - `object_name`: class name of the model
  - `name`: plural name of the model
  - `perms`: a `dict` tracking `add`, `change`, `delete`, and
    `view` permissions
  - `admin_url`: admin changelist URL for the model
  - `add_url`: admin URL to add a new model instance

#### `AdminSite.has_permission(request)`

Returns `True` if the user for the given `HttpRequest` has permission
to view at least one page in the admin site. Defaults to requiring both
[`User.is_active`](/ja/2.2/ref/contrib/auth/#django.contrib.auth.models.User.is_active) and
[`User.is_staff`](/ja/2.2/ref/contrib/auth/#django.contrib.auth.models.User.is_staff) to be
`True`.

#### `AdminSite.register(model_or_iterable, admin_class=None, **options)`

Registers the given model class (or iterable of classes) with the given
`admin_class`. `admin_class` defaults to
[`ModelAdmin`](#django.contrib.admin.ModelAdmin) (the default admin options). If
keyword arguments are given -- e.g. `list_display` -- they'll be applied
as options to the admin class.

Raises [`ImproperlyConfigured`](/ja/2.2/ref/exceptions/#django.core.exceptions.ImproperlyConfigured) if a model is
abstract. and `django.contrib.admin.sites.AlreadyRegistered` if a model
is already registered.

### Hooking `AdminSite` instances into your URLconf

The last step in setting up the Django admin is to hook your `AdminSite`
instance into your URLconf. Do this by pointing a given URL at the
`AdminSite.urls` method. It is not necessary to use
[`include()`](/ja/2.2/ref/urls/#django.urls.include).

In this example, we register the default `AdminSite` instance
`django.contrib.admin.site` at the URL `/admin/`

```
# urls.py
from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),
]
```

### Customizing the [`AdminSite`](#django.contrib.admin.AdminSite) class

If you'd like to set up your own admin site with custom behavior, you're free
to subclass `AdminSite` and override or add anything you like. Then, simply
create an instance of your `AdminSite` subclass (the same way you'd
instantiate any other Python class) and register your models and
`ModelAdmin` subclasses with it instead of with the default site. Finally,
update `myproject/urls.py` to reference your [`AdminSite`](#django.contrib.admin.AdminSite) subclass.

*myapp/admin.py*

```python
from django.contrib.admin import AdminSite

from .models import MyModel

class MyAdminSite(AdminSite):
    site_header = 'Monty Python administration'

admin_site = MyAdminSite(name='myadmin')
admin_site.register(MyModel)
```

*myproject/urls.py*

```python
from django.urls import path

from myapp.admin import admin_site

urlpatterns = [
    path('myadmin/', admin_site.urls),
]
```

Note that you may not want autodiscovery of `admin` modules when using your
own `AdminSite` instance since you will likely be importing all the per-app
`admin` modules in your `myproject.admin` module. This means you need to
put `'django.contrib.admin.apps.SimpleAdminConfig'` instead of
`'django.contrib.admin'` in your [`INSTALLED_APPS`](/ja/2.2/ref/settings/#std-setting-INSTALLED_APPS) setting.

### Overriding the default admin site

> **New in Django 2.1**

You can override the default `django.contrib.admin.site` by setting the
[`default_site`](#django.contrib.admin.apps.SimpleAdminConfig.default_site) attribute of a custom `AppConfig`
to the dotted import path of either a `AdminSite` subclass or a callable that
returns a site instance.

*myproject/admin.py*

```python
from django.contrib import admin

class MyAdminSite(admin.AdminSite):
    ...
```

*myproject/apps.py*

```python
from django.contrib.admin.apps import AdminConfig

class MyAdminConfig(AdminConfig):
    default_site = 'myproject.admin.MyAdminSite'
```

*myproject/settings.py*

```python
INSTALLED_APPS = [
    ...
    'myproject.apps.MyAdminConfig',  # replaces 'django.contrib.admin'
    ...
]
```

### Multiple admin sites in the same URLconf

It's easy to create multiple instances of the admin site on the same
Django-powered website. Just create multiple instances of `AdminSite` and
root each one at a different URL.

In this example, the URLs `/basic-admin/` and `/advanced-admin/` feature
separate versions of the admin site -- using the `AdminSite` instances
`myproject.admin.basic_site` and `myproject.admin.advanced_site`,
respectively:

```
# urls.py
from django.urls import path
from myproject.admin import advanced_site, basic_site

urlpatterns = [
    path('basic-admin/', basic_site.urls),
    path('advanced-admin/', advanced_site.urls),
]
```

`AdminSite` instances take a single argument to their constructor, their
name, which can be anything you like. This argument becomes the prefix to the
URL names for the purposes of [reversing them](#admin-reverse-urls). This
is only necessary if you are using more than one `AdminSite`.

### Adding views to admin sites

Just like [`ModelAdmin`](#django.contrib.admin.ModelAdmin), [`AdminSite`](#django.contrib.admin.AdminSite) provides a
[`get_urls()`](#django.contrib.admin.ModelAdmin.get_urls) method
that can be overridden to define additional views for the site. To add
a new view to your admin site, extend the base
[`get_urls()`](#django.contrib.admin.ModelAdmin.get_urls) method to include
a pattern for your new view.

> **Note**
>
> Any view you render that uses the admin templates, or extends the base
> admin template, should set `request.current_app` before rendering the
> template. It should be set to either `self.name` if your view is on an
> `AdminSite` or `self.admin_site.name` if your view is on a
> `ModelAdmin`.

### Adding a password reset feature

You can add a password reset feature to the admin site by adding a few lines to
your URLconf. Specifically, add these four patterns:

```
from django.contrib.auth import views as auth_views

path(
    'admin/password_reset/',
    auth_views.PasswordResetView.as_view(),
    name='admin_password_reset',
),
path(
    'admin/password_reset/done/',
    auth_views.PasswordResetDoneView.as_view(),
    name='password_reset_done',
),
path(
    'reset/<uidb64>/<token>/',
    auth_views.PasswordResetConfirmView.as_view(),
    name='password_reset_confirm',
),
path(
    'reset/done/',
    auth_views.PasswordResetCompleteView.as_view(),
    name='password_reset_complete',
),
```

(This assumes you've added the admin at `admin/` and requires that you put
the URLs starting with `^admin/` before the line that includes the admin app
itself).

The presence of the `admin_password_reset` named URL will cause a "forgotten
your password?" link to appear on the default admin log-in page under the
password box.

## `LogEntry` objects

#### `class models.LogEntry`

The `LogEntry` class tracks additions, changes, and deletions of objects
done through the admin interface.

### `LogEntry` attributes

#### `LogEntry.action_time`

The date and time of the action.

#### `LogEntry.user`

The user (an [`AUTH_USER_MODEL`](/ja/2.2/ref/settings/#std-setting-AUTH_USER_MODEL) instance) who performed the
action.

#### `LogEntry.content_type`

The [`ContentType`](/ja/2.2/ref/contrib/contenttypes/#django.contrib.contenttypes.models.ContentType) of the
modified object.

#### `LogEntry.object_id`

The textual representation of the modified object's primary key.

#### `LogEntry.object_repr`

The object\`s `repr()` after the modification.

#### `LogEntry.action_flag`

The type of action logged: `ADDITION`, `CHANGE`, `DELETION`.

For example, to get a list of all additions done through the admin:

```
from django.contrib.admin.models import ADDITION, LogEntry

LogEntry.objects.filter(action_flag=ADDITION)
```

#### `LogEntry.change_message`

The detailed description of the modification. In the case of an edit, for
example, the message contains a list of the edited fields. The Django admin
site formats this content as a JSON structure, so that
[`get_change_message()`](#django.contrib.admin.models.LogEntry.get_change_message) can recompose a message translated in the current
user language. Custom code might set this as a plain string though. You are
advised to use the [`get_change_message()`](#django.contrib.admin.models.LogEntry.get_change_message) method to retrieve this value
instead of accessing it directly.

### `LogEntry` methods

#### `LogEntry.get_edited_object()`

A shortcut that returns the referenced object.

#### `LogEntry.get_change_message()`

Formats and translates [`change_message`](#django.contrib.admin.models.LogEntry.change_message) into the current user
language. Messages created before Django 1.10 will always be displayed in
the language in which they were logged.

## Reversing admin URLs

When an [`AdminSite`](#django.contrib.admin.AdminSite) is deployed, the views provided by that site are
accessible using Django's [URL reversing system](/ja/2.2/topics/http/urls/#naming-url-patterns).

The [`AdminSite`](#django.contrib.admin.AdminSite) provides the following named URL patterns:

| Page | URL name | パラメータ |
| --- | --- | --- |
| 目次 | `index` |  |
| Login | `login` |  |
| Logout | `logout` |  |
| パスワードの変更 | `password_change` |  |
| Password change done | `password_change_done` |  |
| i18n JavaScript | `jsi18n` |  |
| Application index page | `app_list` | `app_label` |
| Redirect to object's page | `view_on_site` | `content_type_id`, `object_id` |

Each [`ModelAdmin`](#django.contrib.admin.ModelAdmin) instance provides an additional set of named URLs:

| Page | URL name | パラメータ |
| --- | --- | --- |
| Changelist | `{{ app_label }}_{{ model_name }}_changelist` |  |
| 追加 | `{{ app_label }}_{{ model_name }}_add` |  |
| 履歴 | `{{ app_label }}_{{ model_name }}_history` | `object_id` |
| 削除 | `{{ app_label }}_{{ model_name }}_delete` | `object_id` |
| 変更 | `{{ app_label }}_{{ model_name }}_change` | `object_id` |

The `UserAdmin` provides a named URL:

| Page | URL name | パラメータ |
| --- | --- | --- |
| パスワードの変更 | `auth_user_password_change` | `user_id` |

These named URLs are registered with the application namespace `admin`, and
with an instance namespace corresponding to the name of the Site instance.

So - if you wanted to get a reference to the Change view for a particular
`Choice` object (from the polls application) in the default admin, you would
call:

```
>>> from django.urls import reverse
>>> c = Choice.objects.get(...)
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,))
```

This will find the first registered instance of the admin application
(whatever the instance name), and resolve to the view for changing
`poll.Choice` instances in that instance.

If you want to find a URL in a specific admin instance, provide the name of
that instance as a `current_app` hint to the reverse call. For example,
if you specifically wanted the admin view from the admin instance named
`custom`, you would need to call:

```
>>> change_url = reverse('admin:polls_choice_change', args=(c.id,), current_app='custom')
```

For more details, see the documentation on [reversing namespaced URLs](/ja/2.2/topics/http/urls/#topics-http-reversing-url-namespaces).

To allow easier reversing of the admin urls in templates, Django provides an
`admin_urlname` filter which takes an action as argument:

```html+django
{% load admin_urls %}
<a href="{% url opts|admin_urlname:'add' %}">Add user</a>
<a href="{% url opts|admin_urlname:'delete' user.pk %}">Delete this user</a>
```

The action in the examples above match the last part of the URL names for
[`ModelAdmin`](#django.contrib.admin.ModelAdmin) instances described above. The `opts` variable can be any
object which has an `app_label` and `model_name` attributes and is usually
supplied by the admin views for the current model.

## The `staff_member_required` decorator

#### `staff_member_required(redirect_field_name='next', login_url='admin:login')`

This decorator is used on the admin views that require authorization. A
view decorated with this function will having the following behavior:

- If the user is logged in, is a staff member (`User.is_staff=True`), and
  is active (`User.is_active=True`), execute the view normally.
- Otherwise, the request will be redirected to the URL specified by the
  `login_url` parameter, with the originally requested path in a query
  string variable specified by `redirect_field_name`. For example:
  `/admin/login/?next=/admin/polls/question/3/`.

使い方の例:

```
from django.contrib.admin.views.decorators import staff_member_required

@staff_member_required
def my_view(request):
    ...
```
