我的django模型领域出了什么问题?

Nat*_*tim 2 python django django-forms

我正在尝试将值转换为标准值的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
Run Code Online (Sandbox Code Playgroud)

如果我在表单中使用它,它运行良好.但我想将它用作表格字段.

我试着这样做:

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
Run Code Online (Sandbox Code Playgroud)

但从未调用过干净的方法.你能帮助我吗 ?

Lak*_*sad 6

您正在混合模型字段和表单字段.

需要首先定义表单字段,然后需要提示相应的模型字段将这些表单字段用于模型表单.

请参阅指定-form-field-for-a-model-field文档

基本上,您需要在模型字段上定义一个名为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)
Run Code Online (Sandbox Code Playgroud)

您在上面创建的字段有一个干净的方法,这是表单字段的要求,而不是模型字段

所以,现在你应该定义表单域(已定义的一个,除了从扩展它forms.CharField,而不是models.CharField),然后定义模型字段,按照模型字段创建定义,并且包括像上面的方法.

或者简单地说,您可以选择定义表单字段,并在模型表单中覆盖此特定modelfield的默认表单字段.(在这种情况下,除非从该模型输入数据,否则验证不会发生)