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