Reputation: 53
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!
Upvotes: 5
Views: 2684
Reputation: 3853
You should use the related name of the fields or RelatedModel._meta.get_fields
class ModelOneAdmin(admin.ModelAdmin):
list_display = ('field_one', 'field_two', 'field_three')
inlines = [ModelTwoInline]
def get_list_display(self, request):
extra_fields = [
f.name for model in self.inlines
for f in ModelTwo._meta.get_fields(include_hidden=False)
]
return self.list_display + extra_fields
Upvotes: 3
Reputation: 9428
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.
Upvotes: 9