django - 从表单字段输入中清除额外空格的位置?

Wes*_*ley 7 forms django

我刚刚发现Django不会自动从表单字段输入中删除额外的空格,我想我理解其基本原理('框架不应该改变用户输入').

我想我知道如何使用python的re删除多余的空格:

#data = re.sub('\A\s+|\s+\Z', '', data)
data = data.strip()
data = re.sub('\s+', ' ', data)
Run Code Online (Sandbox Code Playgroud)

问题是我应该在哪里这样做?据推测,这应该发生在一个形式的清洁阶段,但哪一个?理想情况下,我想清理所有额外空格的字段.如果它应该在clean_field()方法中完成,这意味着我必须有很多clean_field()方法基本上做同样的事情,这似乎是很多重复.

如果不是表单的清理阶段,那么可能在表单基于的模型中?

谢谢你的帮助!

W.

pym*_*rco 10

我的方法是从这里借来的.但是我使用mixin而不是继承django.forms.Form.这样我就可以Form和它一起使用它ModelForm.这里定义的方法重写BaseForm_clean_fields方法.

class StripWhitespaceMixin(object):
    def _clean_fields(self):
        for name, field in self.fields.items():
            # value_from_datadict() gets the data from the data dictionaries.
            # Each widget type knows how to retrieve its own data, because some
            # widgets split data over several HTML fields.
            value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))

            try:
                if isinstance(field, FileField):
                    initial = self.initial.get(name, field.initial)
                    value = field.clean(value, initial)
                else:
                    if isinstance(value, basestring):
                        value = field.clean(value.strip())
                    else:
                        value = field.clean(value)
                self.cleaned_data[name] = value
                if hasattr(self, 'clean_%s' % name):
                    value = getattr(self, 'clean_%s' % name)()
                    self.cleaned_data[name] = value
            except ValidationError as e:
                self._errors[name] = self.error_class(e.messages)
                if name in self.cleaned_data:
                    del self.cleaned_data[name]
Run Code Online (Sandbox Code Playgroud)

要使用,只需将mixin添加到表单中即可

class MyForm(StripeWhitespaceMixin, ModelForm):
    ...
Run Code Online (Sandbox Code Playgroud)

此外,如果要在保存没有表单的模型时修剪空白,可以使用以下mixin.默认情况下,不验证没有表单的模型.当我根据从外部rest api调用返回的json数据创建对象时,我使用它.

class ValidateModelMixin(object):
    def clean(self):
        for field in self._meta.fields:
            value = getattr(self, field.name)

            if value:
                # ducktyping attempt to strip whitespace
                try:
                    setattr(self, field.name, value.strip())
                except Exception:
                    pass

    def save(self, *args, **kwargs):
        self.full_clean()
        super(ValidateModelMixin, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

然后在你的models.py中

class MyModel(ValidateModelMixin, Model):
    ....
Run Code Online (Sandbox Code Playgroud)


phi*_*reo 8

创建自定义模型字段,以便自动使用自定义表单字段.

class TrimmedCharFormField(forms.CharField):
    def clean(self, value):
        if value:
            value = value.strip()
        return super(TrimmedCharFormField, self).clean(value)

# (If you use South) add_introspection_rules([], ["^common\.fields\.TrimmedCharField"])
class TrimmedCharField(models.CharField):
    __metaclass__ = models.SubfieldBase

    def formfield(self, **kwargs):
        return super(TrimmedCharField, self).formfield(form_class=TrimmedCharFormField, **kwargs)
Run Code Online (Sandbox Code Playgroud)

然后在你的车型只需更换django.db.models.CharFieldTrimmedCharField


Art*_*ves 6

如何将其添加到def clean(self):表单中?

有关进一步的文档,请参阅:https: //docs.djangoproject.com/en/dev/ref/forms/validation/#cleaning-and-validating-fields-that-depend-on-each-other

您的方法可能如下所示:

def clean(self):
  cleaned_data = self.cleaned_data
  for k in self.cleaned_data:
    data = re.sub('\A\s+', '', self.cleaned_data[k])
    data = re.sub('\s+\Z', '', data)
    data = re.sub('\s+', ' ', data)
    cleaned_data[k]=data
  return cleaned_data
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用`data = data.strip()`而不是那两条第一条(丑陋的)线. (5认同)
  • cleaning_data = super(YourFormClass,self).clean(),因为第1行维护父行为 (2认同)