How to access attributes of the 'User' model extended by another model referenced by a OnetoOneField in admin.py

Viewed 34

In model.py, I have a class extending the User model

class Tutor(models.Model):
    user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)

In admin.py, I tried to access user.id with 'user_id', which works

class TutorAdmin(admin.ModelAdmin):
    list_display = ('user_id', 'contact_number')

enter image description here

However, when I try to access other attributes of 'user' such as username, email with this format

class TutorAdmin(admin.ModelAdmin):
    list_display = ('user_id', 'user_username', 'contact_number')

This occurs enter image description here

What is the format to access attributes such as user.username or user.email?

UPDATE

Solved it with

class TutorAdmin(admin.ModelAdmin):
    @admin.display(description='username')
    def username(self):
        u = self.user
        if u is not None:
            return u.username

    @admin.display(description='email')
    def email(self):
        u = self.user
        if u is not None:
            return u.email


    list_display = ('user_id', username, email, 'contact_number')

Thanks to the solution by Willem Van Onsem

1 Answers

You can define methods and reference these in the list_display:

class TutorAdmin(admin.ModelAdmin):
    list_display = ('user_id', 'contact_number', username)

    @admin.display(description='username')
    def username(self, obj):
        u = obj.user
        if u is not None:
            return u.username

You can however not edit the usernames, since the function defines how to access the data, not how to alter it.

Since the __str__ for the builtin User model returns the username, you can also work with:

class TutorAdmin(admin.ModelAdmin):
    list_display = ('user_id', 'contact_number', user)
Related