Django OneToOneField具有多个相同的相关名称

时间:2012-10-03 16:13:48

标签: django

很抱歉没有描述性的标题,但我真的不知道如何说出这个。

说我有两个模型:

class Person(...):
  name = ... #have an attribute

class Family(...):
  mum = models.OneToOneField(Person)
  dad = models.OneToOneField(Person)

当我有一个包含mumdad的家庭时,我认为调用dad.family会让我家人dad进入。但是,我收到一条错误消息说这与mum属性冲突。这里的解决方案是使用relative_name s。但是从mum方面向家人打电话而不是从dad开始给我这个家庭感觉很奇怪。为什么我不能打电话给dad.family?有人可以向我解释究竟是什么在这里发生冲突吗?

谢谢!

2 个答案:

答案 0 :(得分:5)

问题在于,根据您的模型,Person可能是mum对一个家庭,dad可能属于另一个家庭。

在这种情况下,像这样的查询将是不明确的:

pat = Person.objects.get(name='Pat')
family1.mum = pat
family1.save()

family2.dad = pat
family2.save()

pat.family # Which family do we want?

因此,您需要为每个名称定义反向关系名称(例如,family_as_mum和family_as_dad)

答案 1 :(得分:1)

我知道上面的答案确实回答了问题"为什么会发生冲突",我知道这是一个老问题。但是,我遇到了它试图找到一种方法让代码根据另一列中的条目限制一列中的条目。我没有找到足够的答案,但设法自己解决了。以下是对直接询问的问题的答案,但可能对其他人有所帮助。

from django.db import models

class Person(models.Model):
  name = models.CharField(max_length=255)

class Family(models.Model):
  mum = models.OneToOneField(Person, on_delete=models.SET_NULL, related_name='family_as_mum', null=True)
  dad = models.OneToOneField(Person, on_delete=models.SET_NULL, related_name='family_as_dad', null=True)

  def save(self, *args, **kwargs):
    if Family.objects.filter(mum=self.dad).exists() or Family.objects.filter(dad=self.mum).exists() or self.mum == self.dad:
      return #any person can only be a mum or a dad, not both
    else:
      super(Family, self).save(*args, **kwargs)

  def update(self, *args, **kwargs):
    if Family.objects.filter(mum=self.dad).exists() or Family.objects.filter(dad=self.mum).exists() or self.mum == self.dad:
      return #same as save, don't want them to update a family member in an invalid way
    else:
      super(Family, self).update(*args, **kwargs)

  @staticmethod
  def get_family(person):
    if Family.objects.get(mum=person).exists():
      return Family.objects.get(mum=person)
    elif Family.objects.get(dad=person).exists():
      return Family.objects.get(dad=person)
    else:
      return None

*注意,找到@staticmethod here,认为找一个与父母相关的家庭的功能可能是有用的,因为如果一个人是妈妈或爸爸,我们可能不知道