Django OneToOne字段自我

时间:2016-07-08 07:28:40

标签: python django django-models

如何定义OneToOne与同一Model的关系?

我有一个名为Order的模型,可以与另一个Order配对。现在我想弄清楚如何处理这种关系的模型。

我的想法:

class Order(models.Model):
    paired_order = models.OneToOneField(self)

OR:

class Pairing(models.Model):
    order1 = models.ForeignKey(Order, related_name='pairing')
    order2 = models.ForeignKey(Order, related_name='pairing')
你怎么看?哪个更有效率?

我想简单地调用配对的。所以我会做类似的事情:

order.paired_order 

OR:

order.pairing.paired

我希望这种关系是对称的,所以对于每对订单,我称之为相同的东西并获得配对订单。

配对模型是一个很好的解决方案,因为我可以为这种关系添加额外的信息,但有一个问题,我必须检测它是哪个顺序,所以我无法调用order.pairing.order1,因为我不知道我是否没有打电话给同一个订单。

编辑:

>>> from _app import models
>>> order1 = models.Order(flight_number="xxx")
>>> order2 = models.Order(flight_number="yyy", paired_order=order1)
>>> order1.paired_order.flight_number

退回None object has not ....

问题在于,当我设置order1是order2的配对顺序时,我想要相反的方向相同的东西。因此,order1.paired_order = order2同样执行此操作order2.paired_order = order1

3 个答案:

答案 0 :(得分:1)

ForeignKey不仅接受一个类作为参数,还接受ForeignKey('ModelNameInSameModelsPyFile')ForeignKey('app_name.ModelName形式的字符串名称。

在你的情况下,它可能就像

class Order(models.Model):

     paired = models.ForeignKey('Order', null=True)

您可以在https://docs.djangoproject.com/en/1.8/ref/models/fields/#foreignkey

了解更多信息

答案 1 :(得分:1)

  

配对模型是一个很好的解决方案,因为我可以添加额外的   这种关系的信息。

在这种情况下,您可以对该组"订单进行建模" (您已将其称为配对)并添加快捷方式以检索配对订单。

class OrderPair(models.Model):
    pass        
    # additional information goes here


class Order(models.Model):
    pair = models.ForeignKey(to="OrderPair", related_name="orders")
    # you'll have to add custom validation 
    # to make sure that only 2 orders can belong to the same "OrderPair"

    @property
    def paired_order(self):
         return self.pair.orders.exclude(id=self.id).first()

一旦您完成此工作,您可能还需要缓存配对订单以避免过多查询。在这种情况下,您不需要相关名称,因此您可以使用+(Django中不那么明确的东西)。

class Order(models.Model):
    ...
    cached_paired_order = models.ForeignKey(to='self', related_name='+')

@property
def paired_order(self):
     if self.cached_paired_order:
          ...
     else:
          ...

答案 2 :(得分:0)

自己遇到这个问题,“对称”一词是找到答案的关键:https://code.djangoproject.com/ticket/7689

class Order(models.Model):
    paired_order = models.OneToOneField(self)

def save(self, *args, **kwargs):
    super(Order, self).save(*args, **kwargs)
    self.paired_order.paired_order = self
    super(Order, self.paired_order).save()