2011-10-08 125 views
1

Django外键让我疯狂!我是Django的新手,我一直在研究一个解决方案,我知道这个解决方案必须是三个星期内没有成功的简单问题。我已经搜索了我的问题的答案,但很少有帮助。Django:使用多个外键模型

我有类似以下内容来支持每个人的有多个电话号码和地址的能力模型:

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) 

我有两个问题:

1)当加入的人,电话,和地址是最有效的方式吗?

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

2)当将这个模型序列化到JSON时,我使用了Stuff Django序列化器的版本1.1.0。以下代码仅返回Person数据,但我需要Person和相关的Phone和Address。哪里不对?

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

非常感谢你给予的任何帮助!

编辑:为了澄清,我相信我不能复制以下使用Django的ORM是我的问题(或误解)根:

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

1)号

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

另请阅读文档select_related

+0

谢谢你的帮助。但 '手机= person.phone_set.all()' 给了我以下错误: 'AttributeError的: '人' 对象有没有属性“phone_set'' 什么不同吗? – FlashBIOS

+0

我读过[select_related](https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related),但我无法将其应用于我的情况。我可以用它来从电话到人,但不是从更合理的人到电话和地址。我错过了什么? – FlashBIOS

+0

阅读Pep 8(下次,如果您打算询问打字错误,请直接复制模型) 影响反向关系的另一件事是外键声明中的“related_name”设置。 –

0

1)您应该可以使用此功能获取人员和他的电话/地址的SSE,因为它不是一个多对多的关系:

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

这里最重要的是,你不想使用get()如果返回多个记录它会抛出一个错误。 Get()用于获取单个记录,filter()用于多个记录。

2)我不确定在这里,但您可能需要为您的个人,电话和地址使用单独的JSON字典。我不熟悉WAD的东西,你可能想看看源代码,看看serializers.serialize()期待什么,以及哪些参数正在定义你所得到的。对不起,我不能在那里帮忙。

+1

谢谢。 .filter()就像一个魅力。 – FlashBIOS