0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Django】管理画面に自由記入欄(メモ)をインライン追加する

Last updated at Posted at 2025-05-18

はじめに

この記事は、自由記入欄をDjango管理画面に表示させるためのものです。
具体的には、顧客管理での対応履歴や社内メモなどを想定して、Memoモデルを新規作成し、Customerモデルの管理画面でメモ追加・自由記入ができるようにします。

Customerモデルにmemoカラムを増やすというやり方もありますが、情報集約系のモデルは肥大化しやすく、他方、メモは使うタイミングが限定的( = ほとんどの場面で不要)なことから分離させる方法をとっています。
前者の方法であればModelAdminクラスだけで可能ですが、モデルを分ける後者ならさらにStackedInlineクラスでの実装が必要となります。

この記事でできること

  • 新しいモデルの作成
  • 子モデルのテキストフィールドを、親モデルのDjango管理画面に表示させ、編集・追加できるようにする

目次

  1. Memoモデルの実装
  2. マイグレーションでDBに反映
  3. Django管理画面に表示
  4. 参考

今回の自由記入欄追加に関係する主なディレクトリ・ファイル構成は以下の通りです。

apps/
├── admin.py             # 管理画面で表示・編集するモデルや管理クラスをまとめて登録するファイル
├── admins/
│   ├── __init__.py      # 各管理クラスのimport集約(CustomerAdminのimport)
│   └── customer.py      # Customer管理画面(CustomerAdmin)・MemoInlineの定義
├── models/
│   ├── __init__.py      # 各モデルのimport集約(Customer, Memoもここでimport)
│   ├── customer.py      # Customerモデル本体
│   └── memo.py          # Memoモデル本体

1. Memoモデルの実装

1. models/memo.pyの作成

Customerモデルと1対1で紐づくメモ用モデルを作成します。

# models/memo.py
from django.db import models

class Memo(models.Model):
    customer = models.OneToOneField('Customer', null=False, blank=False, related_name='memos', verbose_name='顧客', on_delete=models.CASCADE)
    memo = models.TextField('メモ')
    created_at = models.DateTimeField('作成日時', auto_now_add=True)
    updated_at = models.DateTimeField('更新日時', auto_now=True)

    class Meta:
        verbose_name = verbose_name_plural = 'メモ'

    def __str__(self):
        return self.customer.name
  • 1顧客につき1メモのみ許容する場合はOneToOneFieldを使います。
  • 複数メモを許容したい場合はForeignKeyに変更してください。

2. models/__init__.pyでのimport

作成したMemoモデルをDjango全体で参照できるよう、models/__init__.pyに以下を追記してください。

from apps.models.memo import Memo

2. マイグレーションでDBに反映

モデルを作成したら、マイグレーションファイルを作成し、DBに反映します。

python manage.py makemigrations
python manage.py migrate

3. Django管理画面に表示

1. admins/customer.pyでのインラインクラス実装

Customer管理画面でMemoをインライン追加・編集できるようにします。

# admins/customer.py
from django.contrib import admin
from django.forms import Textarea
from apps.models import Customer, Memo

# Memoモデルの表示設定
class MemoInline(admin.StackedInline):
    model = Memo
    extra = 0  # 既存のメモのみ表示(空の追加フォームは出さない)
    can_delete = False  # 削除不可
    fields = ('memo',)

    # テキストエリアのカスタマイズ
    def formfield_for_dbfield(self, db_field, request, **kwargs):
        if db_field.name == 'memo':
            kwargs['widget'] = Textarea(attrs={'rows': 10, 'cols': 90})
        return super().formfield_for_dbfield(db_field, request, **kwargs)


# Customerモデルの表示設定
class CustomerAdmin(admin.ModelAdmin):
    inlines = [MemoInline]  # Customer管理画面にメモを追加
    # ...他の設定...
  • MemoInlineCustomerAdmininlinesとして追加してください。

  • テキストエリアのサイズ等をカスタムしたい場合はformfield_for_dbfield関数で設定してください。必須ではないです。

  • can_delete = False で管理画面からの削除を禁止しています。

  • extra = 0 とすることで「空の追加フォームを表示しない」挙動になります(デフォルトは1で、常に空のフォームが1つ表示されます)。

    extraの値による違いはこちら
    • extra = 0:空のフォームは表示されない

      • extra = 0で既存データがないとき → 何も表示されない

      • extra = 0で既存データがあるとき → 既存データのみ表示

    • extra = 1:空のフォームが1つ表示される

      • extra = 1で既存データがないとき → 空のフォームが1つ表示される

      • extra = 1で既存データがあるとき → 既存データ+空のフォームが1つ表示される(1対多の場合)

        ↑上の画像はモデルの設定がForeignKeyの場合です。
        今回のように1対1(OneToOneField)の場合はメモが1つしか許容されないので、既存データがあれば空フォームは表示されません。

2. admin.pyadmins/__init__.pyの確認

  • admins/__init__.pyでCustomerAdminが正しくimportされているか確認してください。

Django管理画面のカスタム管理クラス(ここではCustomerAdmin)を他の場所からimportしやすくするため、apps/admins/__init__.pyで以下のようにCustomerAdminを記載します。

from apps.admins.customer import (
    CustomerAdmin
)

  • Customerモデルの管理画面用クラス(CustomerAdmin)がadmin.pyで正しく登録されているか確認してください。
    ここで登録されていないとDjango管理画面でCustomerAdminが表示されないので注意してください。
# admin.py
from django.contrib import admin
from apps import models
from apps.admins import CustomerAdmin

admin.site.register(Customer, CustomerAdmin)

これでCustomer管理画面でMemoの追加・編集が可能になります。
お疲れさまでした!


参考

Django管理画面の基本概念

ModelAdmin

  • 各モデルの管理画面の表示・編集方法を定義するクラス。
  • admin.site.register(Model, ModelAdmin) で管理画面に登録。

InlineModelAdmin(インライン)

  • 親モデルの編集画面内で、関連する子モデル(ForeignKey/OneToOne/ManyToMany)の編集フォームを表示できる仕組み。
  • 例: Customerの編集画面でMemoをインライン表示。
  • TabularInline(表形式)とStackedInline(縦積み形式)がある。

admin.site.register

  • モデルと管理クラスを管理画面に登録する関数。
  • 登録しないと管理画面に表示されない。

参照URL

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?