1

Django foreign keys are driving me crazy! I'm new to Django, and I've been working on a solution to what I know must be a very simple problem for over three weeks with no success. I've searched for the answers to my questions, but little has helped.

I have a model similar to the following to support each person's ability to have multiple phone numbers and addresses:

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    <...>

class Phone(models.Model):
    person = models.ForeignKey(Person)
    <...>
    number = PhoneNumberField()

class Address(models.Model):
    person = models.ForeignKey(Person)
    <...>
    zipcode = models.CharField(max_length=10)

I have two questions:

1) When joining Person, Phone, and Address is this the most efficient way?

person = Person.objects.get(pk=1)
phone = Phone.objects.get(person=person)
address = Address.objects.get(person=person)

2) When serializing this model to JSON I'm using Wad of Stuff Django Serializers version 1.1.0. The following code returns only Person data, yet I need Person and the related Phone and Address. What is wrong?

print serializers.serialize('json', Person.objects.all(), indent=4, relations=('phone', 'address',))

Thank you so much for any help you can give!

Edit: To clarify, I believe my inability to replicate the following using Django's ORM is at the root of my problems (or misunderstandings):

select * from person
    left join phone
        on phone.person_id = person.id
    left join address
        on address.person_id = person.id
    where person.id = 1

2 Answers 2

2

1) No.

person = Person.objects.get(pk=1)
phones = person.phone_set.all()
addresses = person.address_set.all()

Also read the docs for select_related

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your help. But phones = person.phone_set.all() gives me the following error: AttributeError: 'Person' object has no attribute 'phone_set' What is different here?
I've read select_related but I'm unable to apply it to my situation. I can use it to travel from Phone to Person, but not from the more logical Person to Phone and Address. What am I missing?
Read Pep 8 (and next time, copy your models directly if you're going to ask about typos) The other thing that affects the reverse relation is "related_name" setting on the foreign key declaration.
0

1) You should be able to use this to get the person and his phones/addresses, since it is not a ManyToMany relationship:

person = Person.objects.get(id=1)
phones = Phone.objects.filter(person__id=person.id)
addresses = Address.objects.filter(person__id=person.id)

Most important here is that you don't want to use get() it will throw an error if more than one record is returned. Get() is for getting one single record, filter() is for multiple.

2) I'm not sure here, but you may need to use separate JSON dictionaries for your person, phones, and addresses. I am not familiar with Wad of Stuff, you may want to look at the source code to see what serializers.serialize() is expecting, and which arguments are defining what you get. Sorry, I can't be of help there.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.