Admin siteでmodelを複数に分割して管理する

Admin siteを便利に使いたい

Admin siteでmodelのデータを予めある程度分類できたら便利だと思いませんか。
django.contrib.auth.models.Userを使って試したいと思います。

仕様

  1. Django 1.1以降のバージョンをインストールしてあること。

ユーザ作成

ユーザは以下の設定とします。

admin.py作成

querysetを利用すれば表示するデータを制御できます。

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.db.models import Q

class StaffAdmin(UserAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.filter(Q(is_staff = True) | Q(is_superuser = True))
        return qs

class CustomerAdmin(StaffAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.exclude(Q(is_staff = True) | Q(is_superuser = True))
        return qs

admin.site.unregister(User)
admin.site.register(User, StaffAdmin)
admin.site.register(User, CustomerAdmin)

このままではAlreadyRegisteredというエラーで使用することが出来ません。

proxy models

AlreadyRegisteredエラーを回避するために、Django 1.1からの新機能proxy modelsを使用します。

models.pyに以下を作成します。

models.py

from django.db import models
from django.contrib.auth.models import User

class Customer(User):
    class Meta:
        proxy = True
        app_label = 'auth'
        verbose_name = 'Customer Account'
        verbose_name_plural = 'Customer Accounts'

次にadmin.pyを以下のように変更します。

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.db.models import Q
from appname.models import Customer

class StaffAdmin(UserAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.filter(Q(is_staff = True) | Q(is_superuser = True))
        return qs

class CustomerAdmin(StaffAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.exclude(Q(is_staff = True) | Q(is_superuser = True))
        return qs

admin.site.unregister(User)
admin.site.register(User, StaffAdmin)
admin.site.register(Customer, CustomerAdmin)

Admin siteは

proxymodel01_01

さらに

このままでは見栄えが悪いのでもう少し修正します。

models.py

from django.db import models
from django.contrib.auth.models import User

class Customer(User):
    class Meta:
        proxy = True
        app_label = 'auth'
        verbose_name = 'Customer Account'
        verbose_name_plural = 'Customer Accounts'

class Staff(User):
    class Meta:
        proxy = True
        app_label = 'auth'
        verbose_name = 'Staff Account'
        verbose_name_plural = 'Staff Accounts'

admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from django.db.models import Q
from appname.models import Customer, Staff

class StaffAdmin(UserAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.filter(Q(is_staff = True) | Q(is_superuser = True))
        return qs

class CustomerAdmin(StaffAdmin):
    def queryset(self, request):
        qs = super(UserAdmin, self).queryset(request)
        qs = qs.exclude(Q(is_staff = True) | Q(is_superuser = True))
        return qs

admin.site.unregister(User)
admin.site.register(Staff, StaffAdmin)
admin.site.register(Customer, CustomerAdmin)

proxymodel01_02

データは、

Staff Accounts

proxymodel01_03

Customer Accounts

proxymodel01_04

これを応用すれば色々なことが出来るのではないでしょうか。

twitter 2009-11-11 00:47:17.632042

参照サイト

Recent Updates

URLConf Tip 01 - キャプチャの有無にかかわらず同一のviewで処理する
Markdownの入力補助"wmd"をAdmin siteで使う
ModelFormでfieldのwidgetを変更する
動的なformを作る 6 - Dynamic Inline Admin site編
Formsetsを使う3 - inlineformset_factory編
動的なformを作る 5 - django-dynamic-formset編
Formクラスからメディアを定義する
複数のmodelを結合する 2 - Proxy model編
複数のmodelを結合する 1
ModelFormでfieldの表示順番を変える
Admin siteのwidgetを個別に変更する
formfield_overridesを使ってAdmin siteのwidgetを変更する
Admin siteのlist_displayをカスタマイズする - リンク編
Admin siteのlist_displayをカスタマイズする - 基本編
Admin siteのTextareaの高さを自在に変更する - admin.py編