如何定义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
。
答案 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()