Django(Python)の管理サイトで編集時のみ項目をReadonlyに設定する

Djangoの管理サイトを利用している時に、データを新しく登録する時にはユーザにデータ入力させたいけど、データを編集する時にはデータ更新させたくないデータがあったんですが、ModelAdminが提供している設定項目のreadonly_fieldsを設定するだけだと、新規登録と編集で表示の切り替えができなかったので、その時に行った管理サイトのカスタマイズ方法をメモしておきます。

readonly_fieldsについて

readonly_fieldsを設定する事で、設定した項目をReadonlyにする事ができます。

class SampleAdmin(admin.ModelAdmin):
    readonly_fields = ('code',)

このように書いておくと、「code」という項目がReadonlyとして表示されます。

こんな感じです。

ただ、これだと新規登録時にも「code」がReadonlyで表示されてしまうので、新規登録時と編集時で「code」のReadonly属性を切り替えられるようにしていきます。

Readonly属性を切り替える

下記のようにModelAdminの新規登録用のView生成メソッドと編集用のView生成メソッドをオーバーライドして、readonly_fieldsの設定を追加してあげます。

class SampleAdmin(admin.ModelAdmin):
    def change_view(self, request, object_id, form_url='', extra_context=None):
        self.readonly_fields = ('code',)
        return self.changeform_view(request, object_id, form_url, extra_context)

    def add_view(self, request, form_url='', extra_context=None):
        self.readonly_fields = ()
        return self.changeform_view(request, None, form_url, extra_context)

こうする事で、新規登録時にはreadonly_fieldsの設定が空になり、編集時にはreadonly_fieldsの設定にcodeが追加されます。

新規登録時と編集時でこのように画面が生成されます。

新規登録時

編集時

最後に

ModelAdminViewを生成する直前でreadonly_fieldsの設定を行う事で、新規登録時と編集時でReadonly属性の切り替えを行うことができました。

業務系のシステムなどで、一度登録したコードなどを編集不可としたい場合などに使えます。今まで独自にマスタ管理系の画面を作成してこういった処理を実装していたのであれば、管理サイトを活用してマスタ管理機能を実現してみてはいかがでしょうか。