Reputation: 244
I have a question for django programmer that should be quite easy but at the moment I cannot figure out how to solve.
I have these three models (I simplify as much as I can):
class Nations(models.Model):
label = models.CharField(max_length=200)
iso2 = models.CharField(max_length=2, unique=True)
class Cities(models.Model):
label = models.CharField(max_length=200, null=True)
country_code = models.ForeignKey(Nations, to_field='iso2', on_delete=models.SET_NULL, null=True, verbose_name='Nation')
class Person(models.Model):
username = models.CharField(max_length=200, blank=False)
city = models.ForeignKey(Cities, on_delete=models.SET_NULL, null=True, blank=True)
As you can see, Person model is just connected with Cities model. What I need to do is to set PersonAdmin class in order to add in the admin view a column showing Nations.label value and make it searchable. In the example below I called this field city__country_code__label, just to make you figure out what I mean (but of course it doesn't work because there is no country_code object in Person model).
class PersonAdmin(admin.ModelAdmin):
list_display = ('id', 'username', 'city', 'city__country_code__label')
ordering = ('username',)
raw_id_fields = ('city',)
search_fields = ['username', 'city__label', 'city__country_code__label']
[...]
how can I ask Django to do this?
Thanx in advance!
Upvotes: 4
Views: 7040
Reputation: 308939
Add a method to your model admin that takes a person obj
and returns the country label. Then add the method to list_display
.
class PersonAdmin(admin.ModelAdmin):
def country_label(self, obj):
return obj.city.country_code.label
list_display = ('id', 'username', 'city', 'country_label')
list_select_related = ['city__country_code']
ordering = ('username',)
raw_id_fields = ('city',)
search_fields = ['username', 'city__label', 'city__country_code__label']
See the list_display
docs for more info.
Note I have used list_select_related
to reduce the number of SQL queries.
Upvotes: 7