djangodjango-modelsdjango-rest-frameworkdjango-admindjango-admin-tools

Django Admin can't display attributes in a model with multiple Foreign Keys to another model


Basically I have two models, one for Icons and another for Types which have 3 icons (business rule). In my models.py file I have the following:

class Icon(models.Model):
    name = models.CharField(max_length=60)
    image_URL = models.CharField(max_length=255)
    modified_date = models.DateTimeField(auto_now=True)
    creation_date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.name
class Type(models.Model):
    name = models.CharField(max_length=60)
    modified_date = models.DateTimeField(auto_now=True)
    creation_date = models.DateTimeField(auto_now_add=True)
    icon1 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon1")
    icon2 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon2")
    icon3 = models.ForeignKey(Icon, null=True, blank=True, on_delete=models.SET_NULL, related_name="icon3")

    def __str__(self):
        return self.name

In my admin.py file I have the following:

class TypeAdmin(admin.ModelAdmin):
    list_display = (
        'name',
        'icon1__name',
        'modified_date',
        'creation_date',
        'id'
    )
...

admin.site.register(models.Type, TypeAdmin)

Everything works fine but I can't get it to display the icon's name. This works for other classes which have a single Foreign Key attribute of the same model, however here since there's three Foreign Key attributes of the same model, I get an error:

<class 'app.admin.TypeAdmin'>: (admin.E108) The value of 'list_display[1]' refers to 'icon1__name', which is not a callable, an attribute of 'TypeAdmin', or an attribute or method on 'app.Type'.

What is causing this error? How may I fix it? The FK is allowed to be null (or blank) because some types are allowed to not have icons (not be required).


Solution

  • Solved: thanks to Iain's answer, should not call attribute and only leave it as icon1 instead of icon1__name since it calls the __str__ method which returns the name anyway.