2009-10-28 52 views
2

我想做一個PhoneField,將該值轉換爲標準化值。我的Django模型領域出了什麼問題?

在這種情況下,我想使用這種乾淨的方法。

def clean(self): 
    phone = self.cleaned_data.get('phone') 

    # Is it already standardized ? 
    if phone.startswith('+'): 
     mo = re.search(r'^\+\d{2,3}\.\d{9,11}$', phone) 

     if not mo: 
     raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
     else: 
     return phone 

    # If not, it must be a french number. 
    phone = re.sub("\D", "", phone) # Suppression des caractères séparateurs 

    mo = re.search(r'^\d{10}$', phone) # Numéro à 10 chiffres 
    if not mo: 
     raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
    else: 
     phone = mo.group()[-9:] 

    return u'+33.%s' % phone 

如果我在表單中使用它,它會很好地工作。 但我想用它作爲表單域。

我試圖做這樣的:

EMPTY_VALUES = (None, '') 

class PhoneInput (forms.TextInput): 
    def render(self, name, value, attrs=None): 
     if value not in EMPTY_VALUES: 
      value = phone_render(value) 
     else: 
      value = None 

     return super(PhoneInput, self).render(name, value, attrs) 

class PhoneField(models.CharField): 
    widget = PhoneInput 

    def __init__(self, *args, **kwargs): 
     kwargs['max_length'] = 16 
     super(PhoneField, self).__init__(*args, **kwargs) 

    def get_internal_type(self): 
     return "CharField" 

    def clean(self, value): 
     phone = super(PhoneField, self).clean(value) 

     # Le numéro contient-il un indicatif ? 
     if phone.startswith('+'): 
      mo = re.search(r'^\+\d{2,3}\.\d{9,11}$', phone) 

      if not mo: 
      raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
      else: 
      return phone 

     # Pas d'indicatif : on est en France par défaut 
     phone = re.sub("\D", "", phone) # Suppression des caractères séparateurs 

     mo = re.search(r'^\d{10}$', phone) # Numéro à 10 chiffres 
     if not mo: 
      raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
     else: 
      phone = mo.group()[-9:] 

     return u'+33.%s' % phone 

但清潔方法不會被調用。你可以幫我嗎 ?

回答

6

您正在混合模型字段和表單字段。

表單字段需要首先定義,然後需要相應的模型字段將這些表單字段用於模型表單。

specifying-the-form-field-for-a-model-field documentation

基本上你需要定義模型字段名爲formfield方法

def formfield(self, **kwargs): 
    # This is a fairly standard way to set up some defaults 
    # while letting the caller override them. 
    defaults = {'form_class': MyFormField} 
    defaults.update(kwargs) 
    return super(HandField, self).formfield(**defaults) 

,你在上面產生的磁場,有一個乾淨的方法,這是一種形式的要求場,而不是一個模型場

所以,現在你應該定義表單域(您已經定義了一個,除了從forms.CharField擴展它,而不是models.CharField),然後根據模型字段創建定義來定義模型字段,幷包含上述方法。

或者簡單地說,您可以選擇定義一個表單字段,並在模型表單中覆蓋此特定的modelfield的默認表單字段。 (除非數據是從的ModelForm進入本書雖然是」在這種情況下驗證犯規發生)

1

這裏是我使用becomingGuru幫助:)

class PhoneFormField(forms.CharField): 
    widget = PhoneInput 

    def clean(self, value): 
     phone = super(PhoneFormField, self).clean(value) 

     # Le numéro contient-il un indicatif ? 
     if phone.startswith('+'): 
      mo = re.search(r'^\+\d{2,3}\.\d{9,11}$', phone) 

      if not mo: 
      raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
      else: 
      return phone 

     # Pas d'indicatif : on est en France par défaut 
     phone = re.sub("\D", "", phone) # Suppression des caractères séparateurs 

     mo = re.search(r'^\d{10}$', phone) # Numéro à 10 chiffres 
     if not mo: 
      raise forms.ValidationError(_(u'Vous devez entrer un numéro de téléphone. (+33.389520638 ou 0389520638).')) 
     else: 
      phone = mo.group()[-9:] 

     return u'+33.%s' % phone 

class PhoneField(models.CharField): 
    def __init__(self, *args, **kwargs): 
     kwargs['max_length'] = 16 
     super(PhoneField, self).__init__(*args, **kwargs) 

    def get_internal_type(self): 
     return "CharField" 

    def formfield(self, form_class=PhoneFormField, **kwargs): 
     return super(PhoneField, self).formfield(form_class=form_class, **kwargs) 

感謝您的幫助,我固定它。