【问题标题】:How to make django association reference to itself如何使 django 关联引用自身
【发布时间】:2021-09-10 23:46:06
【问题描述】:

我有:

class Direction(models.Model):
    left = models.OneToOneField(
        'self', on_delete=models.SET_NULL, null=True, related_name='right')
    right = models.OneToOneField(
        'self', on_delete=models.SET_NULL, null=True, related_name='left')

错误:

ant.Direction.left:(fields.E302)“ant.Direction.left”的反向访问器与字段名称“ant.Direction.right”冲突。 提示:重命名字段“ant.Direction.right”,或在字段“ant.Direction.left”的定义中添加/更改相关名称参数。

如何建立这种关系以便a.left = bb.right = a

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    你不能像related_name一样使用已经定义的字段。无论如何,您可能不想使用两个OneToOneFields,您可以定义一个OneToOneField,并将相关名称设置为相反,所以:

    class Direction(models.Model):
        left = models.OneToOneField(
            'self',
            on_delete=models.SET_NULL,
            null=True,
            related_name='right'
        )
        # no right

    所以现在如果方向 a 具有 .left 方向 b,那么 b 具有 .right 对象 @987654327 @。

    如果没有.right,那么访问.right 将引发Direction.DoesNotExist 异常,但是我们可以通过为related_name 使用另一个来解决此问题,并使用将包装它的属性在try-except:

    class Direction(models.Model):
        left = models.OneToOneField(
            'self',
            on_delete=models.SET_NULL,
            null=True,
            related_name='_right'
        )
        
        @property
        def right(self):
            try:
                return self._right
            except Direction.DoesNotExist:
                return None
    
        @right.setter
        def _set_right(self, value):
            self._right = value

    【讨论】:

    • b.right 会返回 Null 还是 raise notfound?
    • @Tjorriemorrie:引发未找到,但您可以通过一个简单的技巧覆盖该行为。
    • @Tjorriemorrie:见更新。在这里,我们使用一个相关的名称 _right,我们编写了一个 getter 和 setter 作为介于两者之间的东西,如果权限不可用,它将返回 None,并在必要时分配给 self._right
    猜你喜欢
    • 2020-04-16
    • 2011-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多