多个外键验证

时间:2016-04-17 09:54:42

标签: python django validation foreign-keys

例如,我们在django教程中使用民意调查应用程序 https://docs.djangoproject.com/en/1.9/intro/tutorial07/

我们可以修改Choice模型以防止通过以下

重复选择文本
class Choice(models.Model):
    question = models.ForeignKey(Question,
                                 on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def clean(self):
        super(Choice, self).clean()
        choice_list = Choice.objects.filter(question=self.question)
        choice_list_text = [a.choice_text for a in choice_list if a.pk != self.pk]
        choice_list_text.append(self.choice_text)
        if len(set(choice_list_text)) != len(choice_list_text):
            raise ValidationError("You have duplicate entries")

    def __str__(self):
        return self.choice_text

在管理员中,Choice模型与问题表单内联。这意味着如果一次编辑一个内联选项,验证将100%有效。我们可以有一个案例如下

Choice: A choice, Votes: 0
Choice: Another choice, Votes: 0

交换

Choice: Another choice, Votes: 0
Choice: A choice, Votes: 0

这会在保存时引发ValidationError。

如果我们想要允许这样的情况,您如何编码验证?如果不可能,如果在管理表单中编辑了一个条目,是否可以使其他内联模型条目不可编辑?

1 个答案:

答案 0 :(得分:0)

如果没有定制很多django开箱即用的formset逻辑,我认为你想要做的事情是不可能的。另请注意,使其他内联条目不可编辑在您的示例中没有帮助,因为两个切换条目都不能单独保存。但有一件事:

在您的情况下,您应该使用clean而不是覆盖unique_together进行验证:

class Choice(models.Model):
    # ...
    class Meta:
        unique_together = (('question', 'choice_text'),)

这将为db级别的每个问题强制执行唯一选择,并且不依赖于clean来调用。