Django Admin - Order by ForeignKey field or method

Django Docs says that in Admin you can only display the __unicode__ representation of a ForeignKey field in list_display and it also allows you to define a custom function if you want to customize the display.
Let's take a simple Blog, Entry as example:
- # models.py
- class Blog(models.Model):
- name = models.CharField(_('Blog Name'), max_length=200)
- desc = models.TextField()
-
- class Entry(models.Model):
- blog = models.ForeignKey(Blog)
- title = models.CharField(max_length=200)
- post = models.TextField()
The target is to have the blog name in the Entry admin list view and also having it sortable.
Of course if will not work if you add it in list_display like 'blog__name'.
- # amin.py
- class EntryAdmin(admin.ModelAdmin):
- list_display = ('title',)
Half is done, you can now see it in admin.
Adding the Blog name in Entry admin
Easy way to do this is to define a function in the Entry model, allowing us to call it in the admin, just like any other field.
- # models.py
- class Blog(models.Model):
- name = models.CharField(_('Blog Name'), max_length=200)
- desc = models.TextField()
-
- class Entry(models.Model):
- blog = models.ForeignKey(Blog)
- title = models.CharField(max_length=200)
- post = models.TextField()
-
- def blog_name(self):
- return self.blog.name
Now we can add it in the admin:
- # amin.py
- class EntryAdmin(admin.ModelAdmin):
- list_display = ('title', 'blog_name')
Making it sortable by
Being a function in the model, it misses an attribute used by the admin admin_order_field to order.
- # models.py
- class Blog(models.Model):
- name = models.CharField(_('Blog Name'), max_length=200)
- desc = models.TextField()
-
- class Entry(models.Model):
- blog = models.ForeignKey(Blog)
- title = models.CharField(max_length=200)
- post = models.TextField()
-
- def blog_name(self):
- return self.blog.name
- blog_name.admin_order_field = 'blog__name'
Now you can actually order the results in entry admin list display by blog name.
Category: Django



Discussion
hello.
I have a question. what if the ForeignKey was in another app.
#models.py
from anotherapp.blog.models import Blog
class Entry(models.Model):
blog = models.ForeignKey(Blog)
title = models.CharField(max_length=200)
post = models.TextField()
how could it be the 'blog_name' definition to show the name of the blog?
#amin.py
class EntryAdmin(admin.ModelAdmin):
list_display = ('title', 'blog_name')
@wilson the code should look the same, it should not matter what app the FK model is from.
hello again. you're right but the problem is when is a relationship "ManyToMany".
what would happen then?
hi I found the answer to my question is like this
def blog_name(self):
return self.blog.all()
this work fine
Yes, for a ManyToMany relantionship that's what you need, self.blog.all()
Very Very useful !!
Thanks a lot man!!
Leave a Comment :
Leave a Comment