Djangoの管理画面のmodelページをカスタマイズする

## はじめに

この記事は[Django Advent Calender 2019](https://qiita.com/advent-calendar/2019/django) 10 日目の記事です

Django はデフォルトで便利な管理画面が付いていますが、さらに便利に使えるようにするためにカスタマイズしていきます。

## 目次

- 表示カラム
- リンクの表示カラム
- カスタムカラム
- 関連キーカラム
- ソート
- 簡易編集
- 検索フィールド
- フィルター Django の管理画面の model ページをカスタマイズする
- 日付ナビゲーション
- カスタムアクションの追加
- 既存アクションの削除
- 関連モデルのリンクカラム

## 一覧(change_list)のカスタマイズ

**表示カラム**

```python
@admin.register(Book)
class BookModelAdmin(adminModelAdmin):
    List_display = ("title", "publisher", "price")
```

**リンクの表示カラム**

```python
@admin.register(Book)
class BookModelAdmin(adminModelAdmin):
    List_display = ("title", "publisher", "price")
    list_display_links = ("title", "price")
```

**カスタムカラム**

```python
@admin.register(Book)
class BookModelAdmin(adminModelAdmin):
    List_display = ("title", "publisher", "price_dollar")

    def price_dollar(self, obj):
        return obj.price * 0.0092
```

**関連キーカラム**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price", "get_establishment")

    def get_establishment(self, obj):
        return obj.publisher.establishment
    get_establishment.short_description = "publisher establishment"
```

**ソート**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    ordering = ("-price",)
```

**簡易編集**
一覧ページで編集することが可能になります。
list_display_links と重複するものは編集することはできない。

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    list_display_links = ("title",)
    list_editable = ("publisher", "price")
```

**検索フィールド**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    search_fields = ("title",)
```

**フィルター**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    list_filter = ("publisher",)
```

**日付**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    date_hierarchy = "publish_date"
```

**カスタムアクジョンの追加**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")
    actions = ["make_published"]

    def make_published(self, request, queryset):
        queryset.update(publish_date=datetime.now())

    make_published.short_description = "Mark selected book as published"
```

**既存アクションの削除**

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price")

    def get_actions(self, request):
        actions = super().get_actions(request)
        if 'delete_selected' in actions:
            del actions['delete_selected']
        return actions
```

**他のモデル一覧に飛ぶリンクを配置**
_他に良い方法があると思うので調査中。_
_ModelAdmin か ChangeList に対してなにかすればよくなる気がしている。_

```python
@admin.register(Book)
class BookModelAdmin(admin.ModelAdmin):
    list_display = ("title", "publisher", "price", "price_dollar", "get_year")
    list_filter = ("publisher",)

@admin.register(Publisher)
class PublisherModelAdmin(admin.ModelAdmin):
    list_display = ("name", "link_to_book")

    def link_to_book(self, obj):
        link = reverse("admin:shop_book_changelist")
        return format_html(
            '<a href="{}?publisher__id__exact={}">{}</a>', link, obj.pk, obj.name
        )
```

## さいごに

今回は管理画面のモデルの一覧表示部分のカスタマイズでした。カスタマイズ自体は編集画面やフォーム・テンプレートなど弄れないところがないくらいにカスタマイズすることができます。ぜひ弄り倒していきましょう。

[Django: Documentation: admin site](https://docs.djangoproject.com/ja/3.0/ref/contrib/admin/)