在 Django 1.7 中,我怎样才能拥有两个必需的模型字段之一?

In Django 1.7, how can I have one of two model fields required?

我正在构建一个基于 django 的网络应用程序来索引一些在线学习资源,例如 MOOCS。一些 MOOCS 是 'open' 意味着它们可以随时开始,按照学习者自己的进度,而其他 MOOCS 有明确的开始和结束日期。对我来说有意义的是,如果课程是开放的,则不应要求开始日期,但如果课程未开放,我希望需要开始日期。在我的 model.py 中有蚂蚁方法可以做到这一点,还是应该仅通过表单验证来处理。感谢您的帮助。

目前:

class Post(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=70)
    description = models.CharField(max_length=300)
    url = models.URLField()
    post_date = models.DateTimeField('date posted')
    start_date = models.DateTimeField('date course starts', null=True, blank=True)
    open = models.BooleanField(default=False)
    ....
    def __unicode__(self):
        return self.title

您似乎知道如何使用表单验证,所以回答您的问题:

您尝试做的事情最好使用您所说的表单验证来完成。现在,如果您想在 模型级别 上以具有完整性的方式执行此操作(不是数据库完整性,而是逻辑完整性),您应该覆盖模型的 clean 方法。您可以通过以下方式执行此操作:

def clean(self, *args, **kwargs):
    if not self.open and not self.start_date:
        raise ValidationError('This course is not open, therefore you need a start date')
    return super(Post, self).clean()

现在,如果您还想在通过命令行 save() 模型实例时强制 clean() 到 运行 来增加逻辑完整性层,您可以调用 self.clean()save() 模型方法中也是如此(请注意,这将在非命令行实例中 运行 self.clean() 两次)。这是最终代码的示例:

class Post(models.Model):
    user = models.ForeignKey(User)
    title = models.CharField(max_length=70)
    description = models.CharField(max_length=300)
    url = models.URLField()
    post_date = models.DateTimeField('date posted')
    start_date = models.DateTimeField('date course starts', null=True, blank=True)
    open = models.BooleanField(default=False)
    ....

    def clean(self, *args, **kwargs):
        if not self.open and not self.start_date:
            raise ValidationError('This course is not open, therefore you need a start date')
        return super(Post, self).clean()

    def save(self, *args, **kwargs):
        self.clean()
        return super(Post, self).save(*args, **kwargs)

    def __unicode__(self):
        return self.title