Django 管理画面のカスタマイズ

## 概要

[前回の記事](https://qiita.com/xinome/items/8319a7f85424bd6e62de)の続きで、バックエンド側の実装を進めました。
Djangoには元々管理画面用のファイル（admin.py）が用意されているのですが、デフォルトの機能だけでは使いづらい部分もあるため公式のリファレンスをもとにカスタマイズをしていきます。


### 実装機能

- DjangoでのModel構築
- Django管理画面のカスタマイズ（admin.py）

| 項番 | 記事 |
| :--- | :--- |
| 1 | [React + Django + CORSを使ったフロントエンド / バックエンドのデータ連携](https://qiita.com/xinome/items/8319a7f85424bd6e62de) |
| 2 | Django 管理画面のカスタマイズ（本記事） |
| 3 | [Django REST framework(DRF)を使ったAPIサーバーとReactとのデータ連携](https://qiita.com/xinome/items/a524522b6697a3d9ffa9) |
| 4 | [Django REST frameworkのserializersを使った外部キーモデルの参照](https://qiita.com/xinome/items/49fdbf5c8cac0bbbcf3a) |
| 5 | [React + Redux / Redux Toolkitを使った非同期通信の検証](https://qiita.com/xinome/items/7971ac9091d126f3861a) |
| 6 | [APIをテストツール「Postman」を使ったDjangoとのCRUD機能実装(設計編)](https://qiita.com/xinome/items/1eaac0c02bf3bf20f75b) |
| 7 | [APIをテストツール「Postman」を使ったDjangoとのCRUD機能実装(実装編)](https://qiita.com/xinome/items/9541aa8afe7d77ea0b1e) |

### 参考文献

- Django公式: Django の admin サイト

https://docs.djangoproject.com/ja/5.0/ref/contrib/admin/#modeladmin-objects

- Django管理画面のオブジェクト一覧ページをカスタマイズ

https://qiita.com/ryo-keima/items/2bb55c05a79929ec9e71



## フォルダ構成

今回使用しているものをメインに抜粋

- バックエンド(Python / Django)

```
[Djangoプロジェクト]
├── [Djangoプロジェクト_meta]
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── [Djangoアプリ]
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   ├── urls.py
│   └── views.py
├── db.sqlite3
└── manage.py
```



## 実装方法

### バックエンド

今回は `ProjectTopics` と言うモデル名を参照します。
また編集を必要とせず、複数のモデルで共通項目として使用するものを `BaseMeta` として定義しています。

- ModelでDB構成の設計

```python:backend_django/django_app/models.py
# 全てのモデルに共通する項目を定義する
class BaseMeta(models.Model):
  created_at = models.DateTimeField(auto_now_add=True)
  updated_at = models.DateTimeField(auto_now=True)

  class Meta:
    abstract = True  # 抽象クラスとして定義する

class ProjectTopics(BaseMeta):
  topic_id = models.AutoField(primary_key=True)
  date = models.DateField()
  content = models.CharField(max_length=1000)

  class Meta:
    db_table = 'project_topics'  # テーブル名を指定する

```

- デフォルトで設計されている `admin.py` にModelを追加

```python:backend_django/django_app/admin.py
from django.contrib import admin

# Register your models here.
from .models import ProjectTopics

admin.site.register(ProjectTopics)

```

- デフォルトのlocalhostである http://127.0.0.1:8000/admin/ を参照します。

```bash
python manage.py runserver
```

■一覧画面
![スクリーンショット 2024-01-10 17.14.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76115/75612ee9-0cc3-6197-9300-7d59ade739df.png)

■編集画面
![スクリーンショット 2024-01-10 17.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76115/009d36a1-8c5e-b451-052f-1a46bb2fce0a.png)


いくつかデータを入れた状態だとこのような表示になるのですが、このままではデータの表示がわかりずらいため、各画面を見やすくするために各ファイルの設定を追加していきます。


```python:backend_django/django_app/models.py
  class Meta:
      :
    verbose_name_plural = 'プロジェクトのトピック一覧'

  def __str__(self):
    return self.content
```

| 指定値 | 内容 |
| :--- | :--- |
| verbose_name_plural | 管理画面で表示されるモデル名を指定する |
| __str__(self) | 管理画面で表示されるモデルの名称を指定する |



`ProjectTopics` モデルを継承した、カスタマイズ用のClass `ProjectTopicsAdmin` を定義します。

```python:backend_django/django_app/admin.py
# admin.site.register(ProjectTopics)

@admin.register(ProjectTopics)
class ProjectTopicsAdmin(admin.ModelAdmin):
  Fields = ('topic_id', 'date', 'content')
  list_display = ('topic_id', 'date', 'content', 'created_at', 'updated_at')
  list_display_links = ('topic_id', )

  search_fields = ('content', )
  list_filter = ('date', )
  list_editable = ('date', 'content')

```

| 指定値 | 内容 |
| :--- | :--- |
| Fields | 編集画面で表示する項目を指定する |
| list_display | 一覧画面で表示する項目を指定する |
| list_display_links | 一覧画面でリンクにする項目を指定する |
| search_fields | 検索ボックスを表示する項目を指定する |
| list_filter | フィルターを表示する項目を指定する |
| list_editable | 一覧画面で編集可能にする項目を指定する |

※ `list_display_links` で指定した項目は、`list_editable` と重複させることはできません。



## 実装レビュー

![スクリーンショット 2024-01-10 18.26.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76115/62686bf2-e2be-e98a-5f3e-93ca7c926911.png)

![スクリーンショット 2024-01-10 18.27.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76115/028f13a0-ed18-2c34-dff3-0447e4316847.png)


models.py, admin.pyそれぞれを指定させることで、以下のような機能が実装されました。

- 一覧画面で抽象クラスを含めたProjectTopicsモデルの各項目を参照する
- 編集画面への遷移を必要とせず、一覧画面で編集できる項目
- 一定のフィルタリングを通した検索ができるように
- 管理画面で表示されるモデル名を変更