0

I have two table(One-To-One relationship) :

class Member(models.Model):
    openid = models.CharField(max_length=32)
    realname = models.CharField(max_length=30, null=True, blank=True)
    nickname = models.CharField(max_length=32)
    join_date = models.DateField()
    ....more data ...


class MemberProfile(models.Model):
    member = models.ForeignKey(Member)
    position = models.ForeignKey(Position)
    mobile = models.CharField(max_length=50, null=True, blank=True)
    email = models.EmailField(null=True, blank=True)
    ....more data ...

Apparently, Member is master table and MemberProfile is slave.
But I find it is inconvenient to get MemberProfile's data through by Member. If Member has a ForeignKey link to MemberProfile,such as :

class Member(models.Model):
    profile = models.ForeignKey(MemberProfile)
    openid = models.CharField(max_length=32)
    realname = models.CharField(max_length=30, null=True, blank=True)
    nickname = models.CharField(max_length=32)
    join_date = models.DateField()
    ....more data ...

I can get the profile from a member more easily.
member = Member.objects.get(id=id)
I can retrieve profile by member.profile rather than one more sentence:profile = MemberProfile.objects.get(member=member)

Is it better to move ForeignKey define in Member ??

Mithril
  • 12,947
  • 18
  • 102
  • 153

2 Answers2

2

Use a OnetoOneField for the member:

class MemberProfile:
    member = models.OneToOneField(Member)

Then you can access a member's profile like this:

member.memberprofile

Relevant quote from the docs:

Conceptually, this is similar to a ForeignKey with unique=True, but the “reverse” side of the relation will directly return a single object.

spinlok
  • 3,561
  • 18
  • 27
  • No, you are wrong.How can you use `member.profile` as you do not define `profile` in `Member`? See [What's the difference between django OneToOneField and ForeignKey?][http://stackoverflow.com/questions/5870537/whats-the-difference-between-django-onetoonefield-and-foreignkey] – Mithril Apr 01 '14 at 04:15
  • 1
    @Mithril yes, that is what django let's you do. It does a 'reverse' lookup and the example you linked to does exactly this. Even though Engine doesn't define a Car field, you can access e.car which is the Car object that has the foreign key to e – spinlok Apr 01 '14 at 05:31
  • I see,it is `memberprofile` , not `profile`.django will auto lowercase the OneToOneField model name.Can I change `memberprofile` to another name? I mean, can I define a name in `Member` as a holder,it would be much more clear for others to understand this model. – Mithril Apr 01 '14 at 06:20
  • @Mithril you can use `related_name` in the field definition to change the reverse accessor. – Daniel Roseman Apr 01 '14 at 07:21
0

As per your models.

class Member(models.Model):
    openid = models.CharField(max_length=32)
    ....more data ...


class MemberProfile(models.Model):
    member = models.ForeignKey(Member)
    position = models.ForeignKey(Position)
    ....more data ...

It is not much inconvenient to get MemberProfile data if we are having Member object

member_object = Member.objects.get(id=1)
print member_object.memberprofile_set.all()     # here you can access MemberProfile 
                                                #data by using reverse relationship

you can customize result as per your need like below :

print member_object.memberprofile_set.filter(mobile='9717353657')
print member_object.memberprofile_set.filter(mobile='9717353657').values_list('email')

also it is better to making Member model as master table.

Prashant Gaur
  • 9,540
  • 10
  • 49
  • 71