模型如何通过Foreignkey与另一个模型相关?

时间:2012-04-21 04:17:19

标签: python django model foreign-key-relationship

所以我一直在网上浏览一下,我找不到我想要的东西。首先说我有

class Contact(models.Model):
    nickname = models.CharField(max_length=25)
    number = models.CharField(max_length=25)
    note = models.TextField()

class Telephone(models.Model):
    contact = models.ForeignKey('Contact')

那么我怎样才能保存昵称/数字/没有,然后能够根据我可以给他们所有的标签找到所有这些?

说我想让它成为当我使用Telephone.objects.filter(contact = jill)时,会提供基于jill实例的所有信息吗?如果我想能够编辑jill并通过不同的保存为她提供多个号码,这怎么可能呢? (但是jill不是她的昵称,而是我放在那里的标签。)一个不好的例子,但是我只是想通过一些可以通过电话过滤的命名实例找到联系方式中的所有信息吗?或者是外键而不是我正在寻找的东西?

1 个答案:

答案 0 :(得分:3)

Telephone.objects.filter(contact__nickname='jill')

请参阅documentation on making queries

 what if i wanted to be able to edit jill and give her more than one number via
 different saves is this possible?

是的。为了给联系对象提供一个多个电话号码,有两种方式 - 通过ForeignKey的一对一关系,或多对多关系。我建议你仔细阅读文档中的models topic

修改

您可以在模型布局中为每个保存提供多个电话号码。

假设Jill有一个新行,所以你想添加一个新的电话号码。你现在的结构方式,首先要在联系人中找到'Jill',然后给她一个新的电话号码:

jill = Contact.objects.get(nickname='jill') # assuming you only have one jill
new_num = Telephone.objects.create(contact=jill,number=5551212)

现在,如果您想要所有Jill的联系人,您可以这样做:

call_jill = Telephone.objects.filter(contact=jill) # if you already pulled jill
call_jill = Telephone.objects.filter(contact__nickname='jill')

另一种方法是使用ManyToMany

   class Telephone(models.Model):
      number = models.PhoneNumberField()

   class Contact(models.Model):
      # your normal fields
      phones = models.ManyToMany(Telephone)

现在,你可以这样做:

   jills_phones = Contact.objects.get(nickname='jill').phones.all()

添加新手机:

   jill = Contact.objects.get(nickname='jill')
   jill.phones.add(Telephone.objects.create(number=5551212))
   jill.save()

你也可以反过来,找出这是谁的手机:

   phone = Telephone.objects.get(number=5551212)
   whose_is_it = phone.contact_set.all()

那有什么区别?

它们听起来都很相似,但差异很微妙。一个简单的比喻很容易。一个制造商可以有许多汽车,但一辆汽车只能有一个制造商 - 这是汽车和制造商之间的一对一。

比萨饼可以有很多浇头,每个浇头都可以放在多个比萨饼上。在这种情况下,Pizza与Toppings有ManyToMany的关系。

你可能会认为我可以用ForeignKey来做到这一点。你是对的,但请考虑这种情况:

假设您开始并且没有浇头。因此,您将橄榄创建为顶部,然后将其添加到比萨饼中。大。

现在你想要同样的披萨也有青椒。现在你被卡住了,因为一个比萨饼只能有一个馅料(由于ForeignKey)。

因此,您最终会创建第三个模型,该模型包含对披萨和顶部的引用。因此,不要在比萨饼上添加浇头,而是将它们放在另一个模型上:

class Pizza(models.Model):
   topping = models.ForeignKey('Topping')

class Topping(models.Model):
   name = models.CharField(max_length=100)

class AssembledPizza(models.Model):
   topping = models.ForeignKey('Topping')
   pizza = models.ForeignKey('Pizza')

但是,如果你使用ManyToMany以正确的方式完成它,你有:

class Pizza(models.Model):
   toppings = models.ManyToMany('Topping')

class Topping(models.Model):
   name = models.CharField(max_length=100)

然后你会这样做:

我假设你是一家新餐馆而且没有配料。有关详细信息,请参阅create的文档。

veggie = Pizza()
veggie.toppings.add(Topping.objects.create(name='Olives'))
veggie.toppings.add(Topping.objects.create(name='Peppers'))
veggie.save()

我希望这会澄清一点。