At 11:43 AM

#Django forms (#python) - prepare field values (e.g. .strip()) of all input fields before validation

I have a form that contains forms.URLField:

class MyForm(ModelForm):
    long_url       = forms.URLField(label=_(u"URL"       ), max_length=300, required=True,)

When a user inputs value that has trailing spaces, default URLField validation fails: Enter a valid URL.

I haven’t found some standardized and elegant way how to allow this, and looking into the source of django.form forms.py and fields.py I found several ways how to workaround this.

Chose inheriting Form._clean_fields method and changing form.data before validation occurs. Form.data is immutable QueryDict instance, so I needed to override this.

Finally:

def _clean_fields(self):
    if "long_url" in self.data:
        orig = self.data._mutable 
        self.data._mutable = True
        self.data["long_url"] = self.data["long_url"].strip()
        self.data._mutable = orig
    return super(MyForm, self)._clean_fields()

This could be generalized, i.e. how to prepare field values for all input fields before validation. Example, remove leading and trailing blanks from all string fields. Create a custom base ModelForm class which needs to be inherited. This implementation is more robust, since it supports MergedDict object too (dict attribute contains list of QueryDicts which are merged):

class MyModelForm(ModelForm):

    def _clean_fields(self):
        for qdict in getattr(self.data, "dicts", [self.data]):
            orig = qdict._mutable 
            qdict._mutable = True
            for k, v in qdict.iteritems():
                if isinstance(v, basestring):
                    qdict[k] = v.strip()
            qdict._mutable = orig
        return super(MyModelForm, self)._clean_fields()



class ShortenUrlNewForm(MyModelForm):

    long_url       = forms.URLField(label=_(u"URL"       ), max_length=300, required=True,)

This can be applied for normal Forms too.

blog comments powered by Disqus