Django Admin: How to display value of fields with list_display from two models which are in oneToOne relation?
Asked Answered
E

3

10

I belive that the answer to my problem is simple, but I can't find it anywhere. Here is my predicament. I have two models: Member and MemberDetail, which are in oneToOne relation like this:

class Member(models.Model):
   ID = models.AutoField(primary_key=True)
   FIRST_NAME = models.CharField('First name', max_length=50)
   LAST_NAME = models.CharField('Last name', max_length=50)
   def __unicode__(self):  
      return u'%s %s' % (self.FIRST_NAME, self.LAST_NAME)

class MemberDetail(models.Model):
   member = models.OneToOneField(Member, primary_key=True)
   DATE_OF_BIRTH = models.DateField('Date of birth')
   EMAIL = models.EmailField('E-mail')
   PHONE = models.CharField('Phone', max_length=15)

Now in my admin.py I want to show table for member with all of his data, like this:

class MemberDetailInline(admin.TabularInline):
    model = MemberDetail

class MemberAdmin(admin.ModelAdmin):
    list_display = ("FIRST_NAME", "LAST_NAME", "date_of_birth", "email", "phone")
    inlines = [
        MemberDetailInline,
    ]

admin.site.register(Member, MemberAdmin)

I simply don't know how to write "date_of_birth", "email" and "phone" part of list_display. The closest thing I could do is adding this after inlines:

def date_of_birth(self, MemberDetail):
    return MemberDetail.DATE_OF_BIRTH
def date_of_birth(self, MemberDetail):
    return MemberDetail.EMAIL
def date_of_birth(self, MemberDetail):
    return MemberDetail.PHONE

but the fields showed empty on page. What is the solution? Thanks.

Electrojet answered 14/1, 2013 at 23:29 Comment(0)
E
18

Finally!!! I solved it. As I thought it was simple, but I had to do it other way around and with multi table inheritance:

models.py
class Member(models.Model):
    ID = models.AutoField(primary_key=True)
    FIRST_NAME = models.CharField('First name', max_length=50)
    LAST_NAME = models.CharField('Last name', max_length=50)

# Using multi table inheritance - automaticly creates one to one field
class MemberDetail(Member):
    DATE_OF_BIRTH = models.DateField('Date of birth')
    EMAIL = models.EmailField('E-mail')
    PHONE = models.CharField('Phone', max_length=15)

Now for admin.py

admin.py
class MemberDetailAdmin(admin.ModelAdmin):
    list_display = ("FIRST_NAME", "LAST_NAME", "DATE_OF_BIRTH", "EMAIL", "PHONE")

admin.site.register(MemberDetail, MemberDetailAdmin)

That's it. Maybe, there is other solutions, but this is good for me.

Electrojet answered 15/1, 2013 at 21:31 Comment(0)
L
0

In case anyone stumbles into this question/problem, I don't know a direct way to access fields from a OneToOne relationship, however, I was able to fix the problem with the following snippet. Notice that I CAN access OneToOne fields in list_filter by using two '_' to access fields of an OneToOne, for example: modelB_fieldOne.

@admin.display(description='Date')
    def transaction_date(self, purchase):
        return purchase.transaction.date

list_display = ('product', 'transaction_date')
list_filter = ('product', 'transaction__date')

Larissa answered 22/7, 2021 at 0:59 Comment(0)
M
-1

You should just be able to do 'member_detail__email', etc. in list_display

Since it's a 1-1 you should have a backref, and associated fields are referenced using two underscores.

Mcclinton answered 14/1, 2013 at 23:42 Comment(5)
Thanks for replay. I'm confused by 'member_detail__email' part. I tried, but if I put it Django reports error that is not a callable or an attribute of 'MemberAdmin' or found in the model 'Member'. I found some code that looks like a solution. It goes like Member.objects.get(), but I don't know how to complet it.Electrojet
what options do you get? Usually it gives you a list.Mcclinton
Another dead end. Says too many values to get or something like that. I like your idea with backref, but just don't get it how to write it. I want solution to be elegant, for example: Member__MemberDetail__EMAIL. But if it's out of "" error and if it's inside "" error. Maybe I'm missing something. The point is that Member doesn't register MemberDetail. It does on admin add form or change form. But in list_display I can't show those fields from MemberDetail.Electrojet
"too many values"...? I meant, when it gave you the "not a callable or an attribute" error, it usually goes on to say "available fields are <a list of fields>" Did it do that?Mcclinton
Sorry for missunderstanding. But no, no such message.Electrojet

© 2022 - 2024 — McMap. All rights reserved.