Что не так с модельным полем моего django? - PullRequest
2 голосов
/ 28 октября 2009

Я пытаюсь создать PhoneField, который преобразует значение в стандартизированное значение.

В этом случае я хочу использовать этот чистый метод.

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

Но чистый метод никогда не вызывается. Вы можете мне помочь?

Ответы [ 2 ]

6 голосов
/ 28 октября 2009

Вы смешиваете поля модели и поля формы.

Сначала должны быть определены поля формы, а затем должны быть запрошены соответствующие поля модели для использования этих полей формы для формы модели.

См. документация по указанию поля формы для поля модели

В основном вам нужно определить метод с именем 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), а затем определить поле модели согласно определениям создания поля модели и включить метод как выше.

В качестве альтернативы и упрощения, вы можете просто выбрать определение поля формы и в форме модели переопределить поле формы по умолчанию для этого конкретного поля модели. (Altho 'в этом случае проверка не происходит, если данные не введены из этой модели)

1 голос
/ 28 октября 2009

Вот как я это исправил с помощью становящейся справкой Гуру:)

 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)

Спасибо за вашу помощь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...