2015-08-03 67 views
2

关于上下文,这里是一个菜单系统。Django 1.8:如何确保模型中的两个域,至少一个或唯一一个必须符合条件?

class Menu(models.Model): 
    ... 


class Link(models.Model): 
    ... 


class MenuItem(models.Model): 
    menu = models.ForeignKey(Menu) 
    submenu = models.ForeignKey(Menu, related_name='submenu', blank=True, null=True) 
    link = models.ForeignKey(Link, blank=True, null=True) 
    position = models.IntegerField() 

我有两个结果我在寻找实现:

  • 至少一个子菜单和链接不能为空(子菜单标题可以有一个链接)
  • 只有一个子菜单和链接必须为空(子菜单标题不能有链接)

任何高级验证对我来说都是新的,因此代码示例会非常有帮助。

在这个例子中,数据将仅通过Django管理

+0

我没有试过这个,所以我不会让它成为答案,但也许你可以使用多表继承?如果你同时使'Menu'和'Link'子类为'MenuItem',那么'MenuItem'将有两个一对一关系,其中只有一个非空。 – Duncan

+0

谢谢,这听起来像获得第二个结果的潜在方式,但不会覆盖第一个结果。 – StringsOnFire

回答

3

加入围绕模型验证该文档是很差。有很多(封闭的)问题涉及它,但它仍然不清楚。

此解决方案,而无需更改任何形式:

class MenuItem(models.Model): 
    ... 

    def clean(self): 
     super(MenuItem, self).clean() 
     if self.submenu is None and self.link is None: 
      raise ValidationError('Validation error text') 

clean()有一些默认的验证功能,所以属于模型需要清洁先调用。

以上确保至少使用了两个字段中的一个字段,如果不是,则引发异常。我只在Admin界面中进行了测试。

我不知道这是否是正确的方法来做到这一点,并希望知道更多的人是否有更好的理解Django中的模型验证。来自其他语言和框架,这感觉就像写自定义验证的自然方式。

相关问题