4

I have two models:

class Person(models.Model):
    person_name = models.CharField(max_length=255)

    def __unicode__(self):
        return self.person_name

and

class Book(models.Model):
    link = models.ForeignKey(Person)
    book_name = models.CharField(max_length=255)
    book_year = models.CharField(max_length=255)
    book_email = models.CharField(max_length=255)

    def __unicode__(self):
        return self.name

admin.py

class PersonAdmin(admin.ModelAdmin):
    inlines = ('BookInline',)
    list_display = ('person_name', ...)

class BookInline(admin.TabularInline):
    model = Book
    extra = 1
    max_num = 1

In PersonAdmin list_display, how can i show the inline model Book fields (title, name, email).

so when i access Person list of entries in django admin, i see:

person name book name book year book email

Linkid
  • 517
  • 5
  • 17
Ahmad Alzoughbi
  • 474
  • 1
  • 5
  • 14
  • Possible duplicate of [Can "list\_display" in a Django ModelAdmin display attributes of ForeignKey fields?](http://stackoverflow.com/questions/163823/can-list-display-in-a-django-modeladmin-display-attributes-of-foreignkey-field) – Linkid Mar 15 '16 at 11:58

3 Answers3

6

The list_display for the PersonAdmin is meant to display each person once. It doesn't really make sense to include attributes from the book model, because then you would have to include the person multiple times if they have more than one book.

Wouldn't it be better to include the person's name on the book's list_display?

class BookAdmin(admin.ModelAdmin):
    inlines = ('BookInline',)
    list_display = ('person_name', 'book_name', 'book_email', 'book_year')

    def person_name(self, obj):
        return obj.link.person_name

admin.site.register(Book, BookAdmin)
Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • the book will have only one entry, and the project doesn't need listing the books, only the Person with their book. In general yes it's better to use your solution, but the requirements of my project is different, and need to include the book details in person listing. – Ahmad Alzoughbi Mar 15 '16 at 12:44
  • Yes, the book will have one entry. The problem is that each person can have more than one book. If you are displaying a person in the person admin, which book should you display? What should you display if no books exist for that person? – Alasdair Mar 15 '16 at 13:06
  • Each person can't have more than one book, since `max_num = 1` is specified in `BookAdmin`. and to answer your question: even if there is multiple books, i want to show the 1st book. and if no books exist (which won't happen since it's required field) but i'll still display a string "No books" for example. – Ahmad Alzoughbi Mar 15 '16 at 13:35
  • `max_num = 1` is only for the admin -- multiple books for the same person could still be added elsewhere. It is easy to add a person without a book - just create a person in the person admin. If you really have one person for each book, then you should use a [`OneToOneField`](https://docs.djangoproject.com/en/1.9/ref/models/fields/#django.db.models.OneToOneField) instead of a foreign key. – Alasdair Mar 15 '16 at 13:49
  • I think the structure of your models is wrong, but if you want to add the fields to the `PersonAdmin`, then my answer shows you how to do it. Create methods e.g. `book_name` on your `PersonAdmin`, then include them in the person admin's `list_display`. – Alasdair Mar 15 '16 at 13:52
  • creating the method `book_name` with `return obj.book.book_title` giving the error `'Person' object has no attribute 'book'`. What i'm doing wrong here? – Ahmad Alzoughbi Mar 15 '16 at 20:40
  • 1
    It doesn't have an attribute `book`, because the foreign key means each person can have multiple books. See the docs on [following relationships backwards](https://docs.djangoproject.com/en/1.9/topics/db/queries/#following-relationships-backward) for more info. – Alasdair Mar 15 '16 at 21:19
2

According to the doc, you can use a callable to display your fields.

Edit (2021/03/21): the link to the 1.9 doc is not working anymore, but the source is still available. I add the link to the dev version too.

Linkid
  • 517
  • 5
  • 17
0
class BookInline(admin.StackedInline):
   model = Book
   extra = 1
   max_num = 1

StackedInline will solve your problem