[Django]管理画面で選択できる外部キーを絞り込む

Django Logo ソフトウェア開発

Django の管理画面でモデルに外部キーが設定されている場合、モデルの登録・編集時にセレクトボックスが表示されるんですが、外部キーに設定されているモデルの全てのリストが表示されてしまい、かなり選択しにくかったので絞り込みとかできないか調べてみました。
例えば、削除フラグを外部キーに指定しているモデルで使用している場合、データの登録時には削除フラグが False のものだけセレクトボックスに表示したいけど、デフォルトの状態だと削除フラグの値にかかわらず全てのデータが表示されているので、どうにかして絞り込みができればといった感じです。
結論から言うと、 limit_choices_to を使用することで外部キーの絞り込みを行うことができました!!
早速実装方法を説明していきたいと思います。

前提条件

  • Python : 3.6.2
  • Django : 3.1.6

こちらのソースをベースに実装していきたいと思います。

GitHub - koichi-ezato/sample
Contribute to koichi-ezato/sample development by creating an...

外部キーの指定先のモデルを追加する

所属モデルを追加で実装していきます。このモデルがユーザの所属として設定される外部キーになります。

class Belong(models.Model):
    """
    所属先
    """
    name = models.CharField(verbose_name='名称', max_length=10)
    delete_flg = models.BooleanField(verbose_name='削除フラグ', default=False)

ユーザモデルに所属先を外部キーとして追加

ユーザモデルに先ほど追加した所属モデルを外部キーとして追加します。

class User(AbstractBaseUser, PermissionsMixin):
...
    belong = models.ForeignKey(to=Belong, on_delete=models.CASCADE, default=None, null=True, blank=True)
...

モデルの情報をmigrateする

下記のコマンドを実行してモデルの情報を migrate していきます。

$ python manage.py makemigrations

$ python manage.py migrate

これで所属モデルが DB に追加され、ユーザモデルに外部キーが設定されました。

所属モデルを管理画面から確認する

所属モデルを管理画面から確認するために、 account アプリケーションの admin.py に所属モデルに関する内容を追記します。

@admin.register(Belong)
class BelongAdmin(admin.ModelAdmin):
    list_display = ['name', 'delete_flg']

ここまで実装できたら下記コマンドを実行してビルトインサーバを起動します。

$ python manage.py runserver

起動できたら、管理サイトへログインして所属先モデルを確認します。

Django ForeignKey Filter 1

この時点だとまだ所属モデルにデータがないので、下記のデータを準備します。

  • 所属1(削除フラグ = False)
  • 所属2(削除フラグ = True)
  • 所属3(削除フラグ = False)
  • 所属4(削除フラグ = True)
  • 所属5(削除フラグ = False)

これらの情報を入力後にユーザの編集画面を確認すると、

Django ForeignKey Filter 2

こんな感じでセレクトボックスから所属を選択できるんですが、「所属2」と「所属4」は削除フラグが True となっているので、論理削除扱いとして「所属1」「所属3」「所属5」だけを選択できるようにしたいと思います。

外部キーの設定に limit_choices_to を使用する

ユーザモデルの所属モデルの外部キーを指定している箇所に limit_choices_to を設定します。

class User(AbstractBaseUser, PermissionsMixin):
...
    belong = models.ForeignKey(to=Belong, on_delete=models.CASCADE, default=None, null=True, blank=True,
                               limit_choices_to={"delete_flg": False})
...

limit_choices_to には連想配列で取得条件を記述できます。 {フィールド名: 条件, フィールド名: 条件,...} といった感じで複数条件を設定することも可能です。
ユーザモデルを更新したので DB のマイグレーションを行います。

$ python manage.py makemigrations

$ python manage.py migrate

マイグレーション完了したら、画面の方を確認してみます。

Django ForeignKey Filter 3

削除フラグ( delete_flg )が True の「所属2・所属4」が表示されなくなり、「所属1・所属3・所属5」だけが表示されるようになりました!!

最後に

システムに論理削除を実装している場合、条件を絞り込んで外部キーのリストを表示するケースは普通にあると思うもで limit_choices_to の設定方法をしっかり覚えておきたいですね。

スポンサーリンク
スポンサーリンク
ソフトウェア開発プログラミング
スポンサーリンク

コメント

タイトルとURLをコピーしました