Search code examples
pythondjangodjango-modelsdjango-admindjango-admin-actions

list_display not showing email_verified field in ModelAdmin Django


I am list displaying the following fields in Django ModelAdmin.

list_display = ['username', 'email_verified', 'cert_password', 'key_name']

in this list the items - username, cert_password and key_name belongs to a a model ModelName and the item email_verified belongs to other model ModelName2.

But I want to display them all to admin in ModelAdmin so for that I created a function def email_verified as below:

class UserAdmin(admin.ModelAdmin):
    list_display = ['username', 'email_verified', 'cert_password', 'key_name']
    def email_verified(self):
        return ModelName2.email_verified
    actions = [my_action_here]

So, when I returned ModelName2.email_verified its showing <django.db.models.query_utils.DeferredAttribute object at 0x7efcca3b9910> in the Admin interface through ModelAdmin.

So, I tried through the following:

class UserAdmin(admin.ModelAdmin):
    list_display = ['username', 'email_verified', 'cert_password', 'key_name']
    def email_verified(self,obj):
        return ModalName2.objects.get().email_verified
    actions = [my_action_here]

But in this case I got the error - get() returned more than one ModalName2 So, how can I do it.

I want to display the value of email_verified in the ModalAdmin (Admin Interface) in the table with the respective username and other fields.

eg. What I want -

Username | Email_Verified | cert_password | Key_name
abcuser  | 1              | asdf          | asdf
bhdjs    | 1              | lkj           | ljk
asdff    | 0              | lkjsd         | ljl

Here are my modals -

class ModelName2(models.Model):
    username = models.OneToOneField(User, on_delete=models.CASCADE)
    email_verified = models.BooleanField(
        default=False,
        help_text="Valid - <b><a>True</a></b> OR <b><a>False</a></b>")

    def __unicode__(self):
        return unicode(self.username)

class ModelName1(models.Model):

    username = models.OneToOneField(User, on_delete=models.CASCADE)
    cert_password = models.CharField(
        max_length=20,
        default='',
        blank=True,
        help_text="<b><a>System Generated - Do not alter</a></b>")
    key_name = models.CharField(
        max_length=15,
        default='',
        blank=True,
        help_text="<b><a>System Generated - Do not alter</a></b>")

    def __unicode__(self):
        return unicode(self.username)

How to do it? I am using Django 1.11.X


Solution

  • ModalName2.objects.get() should return only one object. Otherwise it raise the error. As for your problem you don't need ModalName2.objects.get() queryset actually. Since obj argument is ModelName instance you can just do following:

    def email_verified(self,obj):
        return obj.username.modelname2.email_verified
    

    Note you can access OneToOneField backwards using lowercased model name modelname2.

    Also since username attribute returning User instance, it would be better to rename it to user:

    class ModelName1(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE)
    

    Also I recommend you to join ModelName and ModelName1 as one model and use single OneToOneField instead of two.