Django 1.8:如何确保模型中的两个字段,至少一个或只有一个必须符合条件?

Str*_*ire 8 django validation menu django-models

对于上下文,这是一个菜单系统.

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()
Run Code Online (Sandbox Code Playgroud)

我有两个想要实现的结果:

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

任何高级验证对我来说都是新的,因此代码示例将非常有用.

在此示例中,仅通过Django Admin添加数据

Str*_*ire 9

关于模型验证的文档很差.有许多(封闭的)问题涉及它,但它仍然不清楚.

此解决方案有效,无需更改任何表单:

from django.core.exceptions import ValidationError

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')
Run Code Online (Sandbox Code Playgroud)

clean() 具有一些默认验证功能,因此需要首先调用属于Model的clean.

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

我不知道这是否是正确的方法,如果有人对Django中的模型验证有更好的理解,我很想知道更多.来自其他语言和框架,这确实是编写自定义验证的自然方式.