Django Admin: как отображать поля двух разных моделей в одном виде? - PullRequest
32 голосов
/ 05 августа 2010

Мой сайт использует пользовательскую модель аутентификации пользователя Django и пользовательскую модель UserProfile для хранения некоторых дополнительных данных (день рождения и т. Д.). Есть ли способ создать представление в Django admin, которое объединяет поля из моделей User и UserProfile?

Я подозреваю, что этот фрагмент кода даже не близок, но, возможно, он поможет проиллюстрировать то, что я пытаюсь сделать:

from django.contrib import admin
from django.contrib.auth.models import User
from userprofile.models import UserProfile


class UserProfileAdmin(admin.ModelAdmin):
    list_display = ('name', 'gender', 'User.email') #user.email creates the error - tried some variations here, but no luck.

admin.site.register(UserProfile, UserProfileAdmin)

Сообщение об ошибке:

ImproperlyConfigured: UserProfileAdmin.list_display [2], «User.email» не является вызываемым или атрибутом «UserProfileAdmin» или обнаружен в модели «UserProfile».

В конечном итоге я пытаюсь создать представление администратора, которое имеет имя и фамилию из UserProfile и электронное письмо от пользователя.

Ответы [ 3 ]

41 голосов
/ 05 августа 2010

для отображения электронной почты пользователя вам нужно иметь метод UserProfile или UserProfileAdmin, который возвращает письмо

в профиле пользователя

def user_email(self):
    return self.user.email

или на UserProfileAdmin

def user_email(self, instance):
    return instance.user.email

затем измените свой list_display на

list_display = ('name', 'gender', 'user_email')

Документы по теме: ModelAdmin.list_display

15 голосов
/ 05 августа 2010

Вы можете попробовать использовать InlineModelAdmin , чтобы отобразить формы User и UserPofile в представлении администратора.

Чтобы отобразить информацию профиля пользователя в списке изменений, вы можете создать новый метод, который делегирует значения от UserProfile до User модели.

Например, это должно работать более или менее:)

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

from my_models import UserProfile

class UserProfileInline(admin.StackedInline):
    model = UserProfile
    fk_name = 'user'

class UserAdmin(admin.ModelAdmin):
    list_display = ['get_userprofile_name', 'email']
    list_select_related = True
    inlines = [
        UserProfileInline,
    ]

    def get_userprofile_name(self, instance):
        # instance is User instance
        return instance.get_profile().name

admin.site.unregister(User)
admin.site.register(User, UserAdmin)
0 голосов
/ 27 августа 2015

Используя Ashoks top answer, я сделал фрагмент, который упрощает этот процесс для большого количества полей

class ColumnViewer(object):
    pass

column_list = ('name', 'surname', )

for col in column_list:
    setattr(ColumnViewer, col, lambda s,i : getattr(i, col))

@admin.register(UserProfile)
class UserProfileAdmin(admin.ModelAdmin, ColumnViewer):
    list_display = column_list
...