带有外键的Django模型形式清除方法

pir*_*irr 0 django django-forms

我尝试使用外键覆盖模型形式的clean方法。

模型:

 Doc(Model):
   name = CharField()
   doc_type = ForeignKey(DictDocType)
Run Code Online (Sandbox Code Playgroud)

形成:

    class DocForm(ModelForm):

      class Meta:
        model = Doc
        fields = '__all__'

      def clean_doc_type(self)
        doc_type_name = self.cleaned_data['doc_type']

        try:
            DictDocType.objects.get(name=doc_type_name)
        except DictDocType.DoesNotExist:
            msg = '{0} does not exist in dictdoc {1}.'.format(
                doc_type_name, self.cleaned_data['name'])
            raise ValidationError(msg)
        return name
Run Code Online (Sandbox Code Playgroud)

在测试中,我得到一个错误:

KeyError:“名称”。如果我从味精中删除self.cleaned_data ['name']-我不会得到self.cleaned_data ['doc_type']。

我哪里错了?

Sha*_*ang 5

您不能交叉引用clean_foo方法中的其他字段,因为clean_foo当您位于其中一个字段中时,并不是所有字段的方法都被调用。表单中的某些值可能尚未填充,因此clean_name()在您调用时尚未调用clean_doc_type(),因此您没有self.cleaned_data['name']

这应该在clean方法中完成。Django文档非常明确地记录了这一点:

到窗体的clean()方法被调用时,所有单独的字段clean方法都将运行(前两节),因此self.cleaned_data将填充有迄今为止尚存的任何数据。因此,您还需要记住考虑到以下事实:您要验证的字段可能无法在最初的单个字段检查中幸免。

而且,您的干净方法没有太大意义,根本没有必要。您将无法选择foreignkey中不存在的ModelForm。即使您强制前端这样做,该字段也会自动使验证失败并给出错误:

选择一个有效的选择。foo不是可用的选择之一。