在clean()期间修改Django表单字段的值

在clean()期间修改Django表单字段的值,django,django-forms,Django,Django Forms,我正在向Django应用程序中的表单和自定义字段添加自定义验证。我希望能够在触发错误时修改字段的值。例如,如果出现错误,则应使用clean()更正的字段值重新显示表单,并显示错误消息“下面的数据已更正。再次单击“保存”以确认这些更改是否正确” 我尝试过像这样返回cleaned_data[]中修改过的数据,但不起作用。它正确显示错误,但在重新显示表单时,字段值不会使用更正的HTML进行更新 class T34AtividadeForm(ModelForm): def clean(self)

我正在向Django应用程序中的表单和自定义字段添加自定义验证。我希望能够在触发错误时修改字段的值。例如,如果出现错误,则应使用clean()更正的字段值重新显示表单,并显示错误消息“下面的数据已更正。再次单击“保存”以确认这些更改是否正确”

我尝试过像这样返回cleaned_data[]中修改过的数据,但不起作用。它正确显示错误,但在重新显示表单时,字段值不会使用更正的HTML进行更新

class T34AtividadeForm(ModelForm):
    def clean(self):
        # Return cleaned html
        error,html = fix_imgs(cleaned_data.get("a34_descricao"))
        if error:
            msg = u'Data has been corrected below. Click save again to confirm if these changes are OK';
            self._errors['a34_descricao'] = ErrorList([msg])
            # This doesn't work
            cleaned_data["a34_descricao"] = html
            # This doesn't work either
            self.a34_descricao = html

    return cleaned_data
我也希望对字段执行同样的操作,但是由于错误是由异常触发的,所以我没有机会返回正确的值。与form clean()方法一样,错误会正确显示,但值不会更新

class HTMLField(CharField):
    widget = HTMLTextarea

    def clean(self, value):
        value = super(HTMLField,self).clean(value)
        error,html = fix_imgs(value)
        if error:
            # This doesn't work
            self.value = html
            raise forms.ValidationError(u'Data has been corrected below. Click save again to confirm if these changes are OK.')
        return html

在clean方法中更改self data以更改显示的值

如果表单是模型表单,则更好的方法是获取实例并更正该数据:

inst = my_form.save(commit=False)
if inst.a34_stuff is None: #or incorrect
    inst.a34_stuff = "corrected"
    request.user.message_set.create(message = "Error corrected")
    return HttpResponseRedirect(reverse('your_url_name',
            args=[])

PS:我不确定这是否真的有效。。。不确定表单是否会更改。

这是我尝试过的方法,适用于我:

 inst = my_form.save(commit=False)
 if not inst.a34_stuff: # or incorrect
     inst.data["a34_stuff"] = "corrected"

更新clean()中的值的方法是更新表单数据字典中的值:

self.data["a34_stuff"] = "html"

这是肯定的。

如果更新表单的
self.data
属性,则可以在
clean()
期间修改字段的值
self.data
是该类的一个实例。默认情况下,querydicts是不可变的。要使它们可变,应该使用
.copy()
方法。从文件中:

当在正常请求/响应周期中访问时,request.POST和request.GET处的querydict将是不可变的。要获得可变版本,需要使用QueryDict.copy()


我们无法重新编辑
请求.数据,因为它是一个不可变的dict。你需要复制它,做你的东西并归还它

但在不同的解决方案之后,我发现了这种方法(在Django 2.2.6中进行了测试)

类MyForm(ModelForm):
def清洁(自清洁):
cleaned_data=super(MyForm,self).clean()
self.instance.field='value'
返回已清除的数据

我在另一个clean函数中为特定字段设置了一个值,但它不起作用,因为它被主clean函数覆盖了。要设置并保持该值,请执行以下操作:

  • 没有工作
  • 在这里,它就像一个符咒

这是可行的,但是没有文档记录,直接修改QueryDict对象感觉很难看。此外,我还必须编写一个帮助函数来修改只读QueryDict…@user27478:您能发布您的解决方案吗?在Django 2.0中,
cleaned_data=super().clean()
(或同等版本),修改
cleaned_data
dict,并确保在函数结束时
返回cleaned_data
。请注意,这仅在可编辑表单字段发生更改时有效,否则不会保存任何更改。1.11中也没有!
self.data = self.data.copy()
self.data['your_field'] = 'new value'
    def clean_tipo_cupon(self):
        tipo_cupon = self.cleaned_data['tipo_cupon']
        qscu = mdlcat.TipoCuponVenta.objects.filter(
            id=tipo_cupon, estado_id=1,
        )
        if not qscu.exists():
            wmessage = u'introducido no paso validación'
            raise forms.ValidationError(wmessage)

        qscu = qscu.first()
        if not qscu.default_owner is None:
            self.cleaned_data['default_owner'] = qscu.default_owner.id

        return tipo_cupon

    def clean(self):
        cleaned_data = super().clean()
        for item in self.fields.keys():
            if isinstance(cleaned_data.get(item), str):
                cleaned_data[item] = cleaned_data.get(item).upper()

        # if a default owner is configured by coupon type
        # it will be assigned
        tipo_cupon = cleaned_data['tipo_cupon']
        qscu = mdlcat.TipoCuponVenta.objects.filter(
            id=tipo_cupon, estado_id=1,
        )
        qscu = qscu.first()
        if not qscu.default_owner is None:
            self.cleaned_data['default_owner'] = qscu.default_owner.id

        return cleaned_data