Django-Manytomy模型验证

Django-Manytomy模型验证,django,django-models,Django,Django Models,我有一个模型,其许多字段与此类似(模型词也有一种语言): 当尝试添加新句子时(例如通过django admin),我得到“句子”实例需要有主键值,然后才能使用多对多关系。这意味着在保存self.words之前我无法访问它,但这正是我要做的。有没有办法解决这个问题,这样你就可以验证这个模型了?我真的想直接验证模型的字段 我发现了很多关于这个异常的问题,但是我找不到解决问题的帮助。如果有任何建议,我将不胜感激 无法在模型的clean方法中执行此验证,但您可以创建一个模型表单,用于验证单词的选择 fr

我有一个模型,其许多字段与此类似(模型词也有一种语言):

当尝试添加新句子时(例如通过django admin),我得到
“句子”实例需要有主键值,然后才能使用多对多关系
。这意味着在保存self.words之前我无法访问它,但这正是我要做的。有没有办法解决这个问题,这样你就可以验证这个模型了?我真的想直接验证模型的字段


我发现了很多关于这个异常的问题,但是我找不到解决问题的帮助。如果有任何建议,我将不胜感激

无法在模型的
clean
方法中执行此验证,但您可以创建一个模型表单,用于验证
单词的选择

from django import forms

class SentenceForm(forms.ModelForm):
    class Meta:
        model = Sentence
        fields = ['words', 'language']

    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
然后,您可以自定义
语句
模型管理类,以便在Django管理中使用您的表单

class SentenceAdmin(admin.ModelAdmin):
    form = SentenceForm

admin.register(Sentence, SentenceAdmin)

您不能通过模型上的
clean
方法执行此操作。在Django,M2M关系的运作方式根本不可能。但是,您可以在用于创建
句子的表单上执行此类验证,例如在管理员或网站上的表单中。

根据Django的说法,您可以听到m2m\u changed信号,该信号将触发添加前添加后操作

但是,在多对多关系中使用add()不会调用任何save()方法(bulk参数不存在),而是使用QuerySet.bulk\u create()创建关系。如果在创建关系时需要执行一些自定义逻辑,请收听m2m_changed信号,该信号将触发pre_add和post_add操作


令人遗憾的是,无法在模型中直接验证它。但到目前为止,一个定制的ModelForm对我来说已经足够了。谢谢你的回答!此外,如果您的句子形式也可以在另一个模型(例如段落)中被视为内联,则您还需要将该行
form=SentenceForm
添加到SentenceInline类中。@purefanatic
model.save()
预计不会引发
ValidationErrors
,因此无法直接对其进行验证。对于django 2.2.4,我还必须在元类中添加
fields='\uuuuu all\uuuuuu'
,否则它会抛出以下错误-
django.core.exceptions.impropertlyconfigured:创建没有“fields”属性或“exclude”属性的模型表单是被禁止的
@PushpakDagade使用
fields='\uu all\uuuu>。我已经在上面的示例中添加了一个显式的白名单
fields=['words','language']
。如果您想创建一个单词,您将如何验证它是否与一个句子关联?它的模型定义中没有“句子”字段。不是每个人都使用表单。我认为这是Django的一个巨大缺陷。有人有更好的答案吗?
class SentenceAdmin(admin.ModelAdmin):
    form = SentenceForm

admin.register(Sentence, SentenceAdmin)