Django Admin: как отображать поля из двух разных моделей в одном представлении?
В моем сайте используется пользовательская модель пользовательской аутентификации Django и пользовательская модель UserProfile для хранения некоторых дополнительных данных (день рождения и т.д.). Есть ли способ создать представление в администраторе Django, который объединяет поля как в моделях 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)
Сообщение об ошибке:
Неправильноконфигурированный: UserProfileAdmin.list_display [2], "User.email" не является вызываемым или атрибутом "UserProfileAdmin" или не найден в модели UserProfile.
В конечном счете, я пытаюсь создать представление администратора, которое имеет имя и фамилию из UserProfile и электронную почту от пользователя.
Ответы
Ответ 1
для отображения электронной почты пользователя вам необходимо иметь метод на UserProfile
или UserProfileAdmin
, который возвращает адрес электронной почты
в UserProfile
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')
Ответ 2
Вы можете попытаться использовать InlineModelAdmin, чтобы отображать формы пользователя и 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)
Ответ 3
Используя верхний ответ Ashoks, я сделал фрагмент, который упрощает этот процесс для большого количества полей
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