一尘不染

Django ManyToMany模型验证

django

我有一个模型与ManyToManyField类似(模型Word也有一种语言):

class Sentence(models.Model):
    words = models.ManyToManyField(Word)
    language = models.ForeignKey(Language)
    def clean(self):
        for word in self.words.all():
            if word.language_id != self.language_id:
                raise ValidationError('One of the words has a false language')

当尝试添加新句子时(例如通过django admin),我得到了'Sentence' instance needs to have a primary key value before a many-to-many relationship can be used。这意味着我在保存self.words之前无法访问它,但这正是我想要做的。有什么办法可以解决此问题,以便你仍然可以验证此模型?我真的很想直接验证模型的字段。

我发现了许多与此异常有关的问题,但找不到解决我的问题的帮助。我将不胜感激任何建议!


阅读 290

收藏
2020-04-01

共1个答案

一尘不染

无法在模型的clean方法中进行此验证,但是你可以创建一个模型表单来验证的选择words

from django import forms

class SentenceForm(forms.ModelForm):
    class Meta:
        model = Sentence

    def clean(self):
        """
        Checks that all the words belong to the sentence's language.
        """
        words = self.cleaned_data.get('words')
        language = self.cleaned_data.get('language')
        if language and words:
            # only check the words if the language is valid
            for word in words:
                if words.language != language:
                    raise ValidationError("The word %s has a different language" % word)
        return self.cleaned_data

然后,你可以自定义Sentence模型管理员类,以在Django管理员中使用表单。

class SentenceAdmin(admin.ModelAdmin):
    form = SentenceForm

admin.register(Sentence, SentenceAdmin)
2020-04-01