在clean()期间修改Django表单字段的值并再次验证

时间:2017-10-20 02:52:50

标签: python django modelform

我想做这样的事情:

class UsuarioForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(UsuarioForm, self).__init__(*args, **kwargs)
        self.fields['cpf'].widget.attrs['maxlength'] = 14
        self.fields['telefone'].widget.attrs['maxlength'] = 15
        self.fields['celular'].widget.attrs['maxlength'] = 15



    nome = forms.CharField(widget=forms.TextInput(attrs={'readonly': True,
                                                         'icone': 'fa fa-font'}))

    usuario = forms.CharField(widget=forms.TextInput(attrs={'readonly': True,
                                                         'icone': 'fa fa-user'}))



    def clean(self):

        cleaned_data = self.cleaned_data

        self.data['cpf'] = re.sub("[\.-]", "", self.data['cpf'])

        clean_data_again_to_revalidate_the_field


    class Meta:
        model = Usuario

        exclude = ['codigo', 'estabelecimento', 'dono', 'data', 'estabelecimento', 'cargo', 'usuario']


        widgets = {

            'cpf': forms.TextInput(attrs={'placeholder': Text().cpf(),
                                          'icone': 'fa fa-credit-card',
                                          'id':'cpf',

                                          }),

            'telefone': forms.TextInput(attrs={'placeholder': Text().telefone(),
                                               'icone': 'fa fa-phone'.decode('utf-8'),
                                               'id': Text().telefone()}),

            'celular': forms.TextInput(attrs={'placeholder': Text().celular(),
                                              'icone': 'fa fa-mobile',
                                              'id': Text().celular()}),
        }

我想更改字段CPF以删除点。之后,我想再次验证该字段。有可能吗?

此外,无法接收该值的self.data [' cpf']。它失败了:这个QueryDict实例是不可变的。

我创建了方法clean_cpf,但它永远不会被调用。我认为因为cpf字段没有出现在cleaning_data中,因为我收到数据的格式无效。

此外,cpf不在cleaning_data中。我认为因为无效。 cpf的最大长度为11,但是当它来自屏幕时,该字段有14个字符。这就是我需要更改字段并再次验证它的原因。

1 个答案:

答案 0 :(得分:2)

q& d hack将data中的值直接修复为__init__形式的代码(nb:未经测试的代码):

class UsuarioForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(UsuarioForm, self).__init__(*args, **kwargs)
        if self.data:
            # make the QueryDict mutable
            self.data = self.data.copy()
            # remove dots from data["cpf"]
            if "cpf" in self.data:
                self.data["cpf"] = self.data["cpf"].replace(".", "")
        # ...

但是如果你仍然得到验证错误,当重新显示表单时,“cpf”字段的数据将是没有点的渲染器。

更清洁的解决方案是使用自定义“CreditCard”字段,因为您的cpf字段似乎需要信用卡号。网上有几个第三方的实现,可以开箱即用,或者至少提供一个起点。

作为旁注:您覆盖表单Meta中的默认小部件,然后覆盖表单__init__中相同字段的“max_length”,这不是很干。您应该直接在Meta.widgets部分设置maxlength。