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)
因为未设置父级,或者不是正确的父类别
我在哪里可以为管理员进行表单验证?和其他形式(因为任何用户都可以添加新的地方,并且必须选择正确的类别)
使用信号,更具体地说是m2m_changed信号.
花时间阅读文档,因为信号不易获取,而且m2m_changed最复杂,因为它是附加到m2m关系的所有信号的一个信号.
基本上你要检查动作是什么pre_add,如果类别父类不符合你的要求,则引发ValidationError.
采取检查的是一些时间sender和instance,espacially因为它根据价值的变化reverse.
更新:
在 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),它会自动添加类别及其父类别,及其父类别等等。这还没有经过测试,但即使它不起作用,它也应该能说明问题。