web-dev-qa-db-fra.com

Django Admin: comment afficher les champs de deux modèles différents dans la même vue?

Mon site utilise le modèle d'utilisateur d'authentification utilisateur de Django et un modèle personnalisé UserProfile pour stocker des données supplémentaires (date de naissance, etc.). Existe-t-il un moyen de créer une vue dans Django admin qui tisse ensemble les champs des modèles User et UserProfile?

Je soupçonne que cet extrait de code n'est même pas proche, mais cela aidera peut-être à illustrer ce que j'essaie de faire:

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)

Message d'erreur:

ImproperlyConfigured: UserProfileAdmin.list_display [2], 'User.email' n'est pas un appelable ou un attribut de 'UserProfileAdmin' ou n'est pas trouvé dans le modèle 'UserProfile'.

En fin de compte, j'essaie de créer une vue administrateur comportant le nom et le prénom de UserProfile et un courrier électronique provenant de User.

32
Joe

pour afficher le courrier électronique d'un utilisateur, vous devez disposer d'une méthode sur UserProfile ou UserProfileAdmin qui renvoie le courrier électronique.

sur UserProfile

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

ou sur UserProfileAdmin

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

puis changez votre list_display en

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

Documents liés: ModelAdmin.list_display

38
Ashok

Vous pouvez essayer d’utiliser InlineModelAdmin pour afficher les formulaires User et UserPofile dans une vue admin. 

Pour afficher les informations de profil utilisateur dans la liste des modifications, vous pouvez créer une nouvelle méthode qui délègue les valeurs de UserProfile à User model.

Par exemple, cela devrait fonctionner plus ou moins :)

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)
15
Davor Lucic

À l'aide d'Ashoks, j'ai créé un extrait simplifiant ce processus pour un grand nombre de champs.

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
0
user1267757