如何在Django中的多对多关系中使用add()时执行验证?

Jul*_*ien 5 django many-to-many

我有一个具有父/子自我关系的分类模型对于主要类别和子类别:

class Place(models.Model):
    name = models.CharField(_("name"), max_length=100)
    categories = models.ManyToManyField("Category", verbose_name=_("categories"))

class Category(models.Model):
    name = models.CharField(_("name"), max_length=100)
    parent = models.ForeignKey('self', blank=True, null=True, related_name='child_set')
Run Code Online (Sandbox Code Playgroud)

我需要防止孤儿,以防止这种错误(在管理员网页界面)

c_parent = Category(name='Restaurant')
c_parent.save()

c_child = Category(name="Japanese restaurant", parent=c_parent)
c_child.save()

place1 = Place (name="Planet sushi")
place1.save()
place1.categories.add(c_parent)
place1.categories.add(c_child)
Run Code Online (Sandbox Code Playgroud)

所以现在我们有了一个名为"Planet sushi"的新地方,它是一个餐厅(根类别)和一个日本餐厅(子类别)

但我想阻止这种事情:

place2 = Place (name="Tokyofood")
place2.save()

place2.categories.add(c_child)
Run Code Online (Sandbox Code Playgroud)

因为未设置父级,或者不是正确的父类别

我在哪里可以为管理员进行表单验证?和其他形式(因为任何用户都可以添加新的地方,并且必须选择正确的类别)

e-s*_*tis 6

使用信号,更具体地说是m2m_changed信号.

花时间阅读文档,因为信号不易获取,而且m2m_changed最复杂,因为它是附加到m2m关系的所有信号的一个信号.

基本上你要检查动作是什么pre_add,如果类别父类不符合你的要求,则引发ValidationError.

采取检查的是一些时间senderinstance,espacially因为它根据价值的变化reverse.


Bra*_*nry 1

更新:

在 Place 类中添加此方法:

def add_cat(self,cat):
    self.categories.add(cat)
    if cat.parent:
        self.add_cat(cat.parent)
Run Code Online (Sandbox Code Playgroud)

place1.categories.add(cat)现在您可以使用而不是使用place1.add_cat(cat),它会自动添加类别及其父类别,及其父类别等等。这还没有经过测试,但即使它不起作用,它也应该能说明问题。