views:

3473

answers:

8

I have a Person model that has a foreign key relationship to Book. Book has a number of fields, but I'm most concerned about "author" (a standard CharField).

With that being said, in my PersonAdmin model, I'd like to display "book.author" using "list_display". I've tried all of the obvious methods for doing so (see below), but nothing seems to work. Any suggestions?

class PersonAdmin(admin.ModelAdmin):
  list_display = ['book.author',]
+3  A: 

According to the documentation, you can only display the __unicode__ representation of a ForeignKey:

http://docs.djangoproject.com/en/dev/ref/contrib/admin/#list-display

Seems odd that it doesn't support the 'book__author' style format which is used everywhere else in the DB API.

Turns out there's a ticket open for this feature, which is marked as Accepted.

insin
+7  A: 

As another option, you can do look ups like:

class UserAdmin(admin.ModelAdmin):
    list_display = (..., 'get_author')

    def get_reviews(self, obj):
        return '%s'%(obj.book.author)
    num_reviews.short_description = 'Author'
jobscry
Should 'get_author' be 'get_reviews'?
Huuuze
whoops, nice catch!
jobscry
A: 

This one's already accepted, but if there are any other dummies out there (like me) that didn't immediately get it from the accepted answer, here's a bit more detail.

The model class referenced by the ForeignKey needs to have a unicode method within it, like so:

class Category(models.Model):
name   = models.CharField(max_length=50)

def __unicode__(self):
 return self.name

That made the difference for me, and should apply to the above scenario. This works on Django 1.0.2.

+1  A: 

You can show whatever you want in list display by using a callable. It would look like this:


def book_author(object):
  return object.book.author

class PersonAdmin(admin.ModelAdmin):
  list_display = [book_author,]
A: 

AlexRobbins' answer worked for me, except that the first two lines need to be in the model (perhaps this was assumed?), and should reference self:

def book_author(self):
  return self.book.author

Then the admin part works nicely.

A: 

And what about ordering support for this column? Looks like it doesn't...

A: 

And how to change the name of column header? e.g. book_author displays the author as values but the column header is always the name of the method and that's in my case not the best solution - any ideas?

DarkLoG
To change the column header, see the short_description option in jobscry's answer above.
shacker
Just what I was wondering, thanks folks.
mlissner
+1  A: 

Like the rest, I went with callables too. But they have one downside: by default, you can't order on them. Fortunately, there is a solution for that:

def author(self):
    return self.book.author
author.admin_order_field  = 'book__author'
Terr