28

我正在向我的 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

我也想对字段做同样的事情,但由于错误是由异常触发的,我没有机会返回更正的值。与表单 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
4

7 回答 7

9

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

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

self.data = self.data.copy()
self.data['your_field'] = 'new value'
于 2018-12-25T19:44:18.737 回答
7

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

于 2009-03-17T14:11:49.097 回答
2

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

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

这肯定有效。

于 2015-11-24T20:22:21.133 回答
1

我们不能重新编辑request.data ,因为它是不可变的 dict。你需要复制它,做你的东西并返回它。

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

class MyForm(ModelForm):

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        self.instance.field = 'value'
        return cleaned_data

于 2019-11-02T14:24:43.520 回答
1

我正在为另一个清理函数中的特定字段设置一个值,但它不起作用,因为它被主清理函数覆盖。为了设置值并保留它:

  • 没有工作。
    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
于 2020-03-17T15:11:35.833 回答
0

这是我尝试并为我工作的方式:

 inst = my_form.save(commit=False)
 if not inst.a34_stuff: # or incorrect
     inst.data["a34_stuff"] = "corrected"
于 2011-07-21T10:57:44.220 回答
-2

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

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:我不确定这是否真的有效......不确定表格是否会改变。

于 2009-03-18T18:30:18.850 回答