Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show information of subclass in list_display django

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!

like image 509
Zenit Polar Avatar asked Jan 19 '23 17:01

Zenit Polar


1 Answers

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.

like image 152
Luke Sneeringer Avatar answered Jan 22 '23 08:01

Luke Sneeringer