Display field from another model in ModelAdmin of User model

Viewed 41

My Django project is based on built-in User model.

For some extra attributes, I have defined another model:

models.py:

class Status(models.Model):
    email = models.ForeignKey(User, on_delete=models.CASCADE)

    is_verified = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return self.email

And here's the custom ModelAdmin:

admin.py:

class CustomUserAdmin(UserAdmin):
    model = User
    list_display = ['email']
    search_fields = ['email']

I want list_display to show me is_verified and is_active fields from Status model but I'm lost.

I've looked into some similar questions on SO like Display field from another model in django admin or Add field from another model Django but none of the solutions are applicable because one of my models is Django's built-in.

1 Answers

do you want this?

models.py

class Status(models.Model):
    # email = models.ForeignKey(User, on_delete=models.CASCADE)
    email = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='status'
    )

    is_verified = models.BooleanField(default=False)
    is_active = models.BooleanField(default=False)

    def __str__(self):
        return self.email

admin.py

class CustomUserAdmin(UserAdmin):
    model = User
    list_display = ['email', 'is_verified', 'is_active']
    search_fields = ['email']
    
    def is_verified(self, obj):
        return obj.status.is_verified
    
    def is_active(self, obj):
        return obj.status.is_active

If you want to apply the displayed name or ordering, please refer to the following source


I saw your comments and tried running the code myself. There were some problems, so I modified admin.py as follows.

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

admin.site.unregister(User)


@admin.register(User)
class CustomUserAdmin(UserAdmin):
    list_display = ['email', 'status_is_verified', 'status_is_active']
    list_filter = ['status__is_verified', 'status__is_active']
    search_fields = ['email']
    
    @admin.display(ordering='status__is_verified')
    def status_is_verified(self, obj):
        return obj.status.is_verified
    
    @admin.display(ordering='status__is_active')
    def status_is_active(self, obj):
        return obj.status.is_active
Related