2017-10-20 106 views
0

我想要做这样的事情:修改值()和验证再次

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字段不会出现在cleared_data中,因为在我接收数据的格式中无效。

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

+0

如果QueryDict实例在使用不同的值重新分配之前是不可变的,请尝试'self.data._mutable = True'然后'self.data ['cpf'] = re.sub(“[\ .-] “,”“,self.data ['cpf'])'尽管这应该不太受欢迎。 –

+0

@ArpitGoyal QueryDict._mutable是一个受保护的属性,你不应该触摸它(除非你真的知道你在做什么,并且没有其他明智的解决方案)。在这种情况下,有一个_documented_正确的方法来获取可变的QueryDict:“要获得可变版本,您需要使用QueryDict.copy()” –

+0

@DiegoMartins:如果链接的问题无法解决您的问题,请发表评论解释为什么 - 也许你需要一个自定义的FormField,或者你应该更好地接受匹配正则表达式的虚线值... –

回答

1

A Q & d黑客将解决直接在窗体的__init__data值(注:未经测试的代码):

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部分设置最大长度。

+0

非常感谢。它的工作,我能够在验证和模型表单工作之前修改CPF。非常感谢。 –