Django Logo

[Django]管理者サイトの一覧のカラムをカスタマイズする

Django の管理サイトの開発してる時に、例えばアカウント管理の一覧などはこんな感じになると思います。

Django Admin 1

まぁ、これでも悪くはないんですが、一覧として表示するのであれば、「苗字」と「名前」は一つのカラムにしたかったり、郵便番号〜番地も「住所」として一つのカラムにしたいことがあると思います。

Django Admin 2

イメージとしてはこんな感じです。

今回はこういった複数のフィールドを一つのカラムとして表示する方法を説明していきたいと思います。
メインの処理以外は下記のサイトのソースを参考にしてもらえればと思います。

一覧のカラムのカスタマイズ

accounts アプリケーションの admin.py のファイルに以下を実装します。

    list_display = ['username', 'name', 'email', 'merge_address']

name 」は User モデルの last_namefirst_name を結合したフィールド( Virtual Field )。「 merge_address 」は zipprefecturecityaddress を結合したフィールド( Virtual Field )になります。

    def name(self, obj):
        return obj.last_name + ' ' + obj.first_name

    name.short_description = '氏名'

    def merge_address(self, obj):
        address = ''
        if obj.zip:
            address += obj.zip + '<br>'
        if obj.prefecture:
            address += obj.prefecture + '<br>'
        if obj.city:
            address += obj.city + '<br>'
        if obj.address:
            address += obj.address

        return mark_safe(address)

    merge_address.short_description = '住所'

Virtual Field の処理を実装します。
admin.py ファイル全体としては下記のようになります。

# admin.py
from django.contrib import admin
from django.contrib.auth.hashers import make_password
from django.utils.safestring import mark_safe

from .models import User

@admin.register(User)
class UserAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        """
        モデルの保存
        :param request:
        :param obj:
        :param form:
        :param change:
        :return:
        """
        if change:
            user = User.objects.get(pk=obj.pk)
            if not user.password == obj.password:
                obj.password = make_password(obj.password)
        else:
            obj.password = make_password(obj.password)
        obj.save()

    list_display = ['username', 'name', 'email', 'merge_address']
    ordering = ['username']

    def name(self, obj):
        return obj.last_name + ' ' + obj.first_name

    name.short_description = '氏名'

    def merge_address(self, obj):
        address = ''
        if obj.zip:
            address += obj.zip + '<br>'
        if obj.prefecture:
            address += obj.prefecture + '<br>'
        if obj.city:
            address += obj.city + '<br>'
        if obj.address:
            address += obj.address

        return mark_safe(address)

    merge_address.short_description = '住所'

最後に

システムによっては Django の管理サイトをメインで利用することもあるかもしれませんが、一覧に1フィールドずつ表示しているとどうしても表示領域の関係上見づらくなることもあると思います。その際は今回の様にフィールドを上手に結合することで、ユーザの視認性を向上させることも可能になります。

ちなみに Django 2 以降 allow_tags は利用できませんので、 HTML タグを利用する場合は、 mark_safe メソッドを利用するようにしましょう。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です