【问题标题】:How to prevent many-to-many class to link to the same objects?如何防止多对多类链接到相同的对象?
【发布时间】:2016-09-18 23:31:13
【问题描述】:

在我的用户模型中,我指定了这个:

friends = models.ManyToManyField(
    'self', 
    blank=True, 
    symmetrical=False, 
    through='Relationship')

这是我正在使用的那个类:

class Relationship(models.Model):
    person1 = models.ForeignKey(
        User, 
        on_delete=models.CASCADE, 
        related_name="person1")

    person2 = models.ForeignKey(
        User, 
        on_delete=models.CASCADE, 
        related_name="person2")
        is_active = models.BooleanField(default=False)

    class Meta:
        unique_together = (('person1', 'person2'),)

对于unique_together,我尝试将多对多关系设为单向,即如果具有指定键的相同对象以相反的顺序存在,则防止创建多对多对象,但它不起作用。此外,这种关系似乎不能是对称的,因为如果我将该属性设置为 true,它会给我一个错误,说明使用自定义类是不可能的。
我还想做一件事 - 防止创建具有相同外键的 m2m 对象。在互联网上搜索时,我发现了 Django 文档中关于 overriding model functions 的部分,所以如果我采用这种方法,结果将是:

def save(self, *args, **kwargs):
    if self.person1 == self.person2:
        return
    else:
        super().save(*args, **kwargs)

我的问题如下:有人可以帮助我创建对称关系吗,这种方法是否好,或者有更好的方法来实现?

【问题讨论】:

  • 也许你应该防止通过表单验证创建相同的朋友
  • @WenZhu 表单验证是一个不错的补充,但恕我直言,它可以/不应该取代模型级验证。

标签: python django django-models many-to-many


【解决方案1】:

如果你是那个意思:

  1. 你不想要被欺骗的关系
  2. 一个人不能引用自己
  3. A 和 B 之间的关系与 B 和 A 之间的关系相同,并且应该只允许一个关系

然后覆盖 unique_together 将强制执行 1。自定义 save() 将强制执行 2. 和 3。

所以在这种情况下需要这两种技术。

另一种方法是使用pre_save 信号来达到同样的效果。但是覆盖 save 更简单,更明确 IMH.O

【讨论】:

  • 感谢您发表意见。我现在发现unique_together 不是防止使用键创建 m2m 对象的解决方案,反之亦然,所以我在上面编辑了我的问题。此外,似乎关系不能是对称的,因为如果我将该属性设置为 True,那么它会给我一个错误,说明使用自定义类是不可能的。你能帮我解决这个问题吗?
  • 你能详细说明你的问题吗?我说你不想要被欺骗的关系是正确的,一个人不能引用自己,A 和 B 之间的关系与 B 和 A 之间的关系相同,并且应该只允许一个关系?
  • 是的,你猜对了。抱歉没有解释得简单一点。
猜你喜欢
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多