Show information of subclass in list_display django

Issue

I have two classes in models.py:

class ModelOne(models.Model):
   field_one = models.CharField(max_length=100)
   field_two = models.CharField(max_length=200)
   field_three = models.CharField(max_length=300)
   [...] #other fields
   def __unicode__(self):
       return self.field_one

class ModelTwo(models.Model):
   relation_model_one = models.ForeignKey(ModelOne)
   other_field = models.CharField(max_length=50)
   [...]
   def __unicode__(self):
       return self.relation_model_one.field_one

And your administration in admin.py is this:

class ModelTwoInline(admin.StackedInline):
    model = ModelTwo
    extra = 0

class ModelOneAdmin(admin.ModelAdmin):
    list_display = ('field_one', 'field_two', 'field_three',)
    inlines = [ModelTwoInline]

My question is:
Can I display the fields of the ModelTwo in list_display of the ModelOne? (The same for list_filter and search_fields)

I need this because I have many subclasses related to the main class!

Solution

You can display anything you want in list_display by writing an instance method with the @property decorator, which then returns whatever you need, and including it in list_display. I don’t think that works for list_filter though.

So, let’s return to your ModelOne class:

class ModelOne(models.Model):
    [...]

    def __unicode__(self):
        return self.field_one

    @property
    def model_two_other_field(self):
        return ', '.join([m2.other_field for m2 in self.modeltwo_set.all()])

Then, in your ModelOneAdmin:

class ModelOneAdmin(admin.ModelAdmin):
    list_display = ('field_one', 'field_two', 'field_three', 'model_two_other_field')
    [...]

I would note, for the record, that when you do this, you’ll be requiring a database hit for every ModelOne instance being displayed. So, if you’re listing 50 instances, you’re incurring the overhead of 50 separate queries (one for each call of self.modeltwo_set.all()). That doesn’t necessarily mean you shouldn’t do it — it might be the right answer, depending on your situation. Just be aware that it could be quite an expensive operation.

Answered By – Luke Sneeringer

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published