I need do modify data incoming to Form
before cleaning. I made it work, but It looks awful:
def __init__(self, *args, **kwargs):
if
Make data
the first argument of the __init__
method, the same as the super class Form
. That way you don't have to dig about in args
or kwargs
.
def __init__(self, data=None, *args, **kwargs):
if data is not None:
data = data.copy() # make it mutable
data['content'] = ' '.join(data['content'].strip().split())
super(TagForm, self).__init__(data, *args, **kwargs)
You can compress the if
/ elif
/ else
onto one line easily enough:
def __init__(self, *args, **kwargs):
data = args[0] if args else kwargs.get('data', None)
if data:
data['content'] = ' '.join(data['content'].strip().split())
super(TagForm, self).__init__(*args, **kwargs)
if args
works as well as if len(args) > 0
because length == 0
items are False
and length > 0
items are True
.
if data
works as well as if data is not None
because you're assuming that data
has at least one key if it's not None
anyway, and if it has a key it's True
.
As stated in the documentation for form and field validation you can not do it on form level, so the __init__
method seems the most legit way. You can of course also modify the data before passing it to the form (for example in your view or wherever you process the form).
I found another solution:
def clean(self, *args, **kwargs):
data = dict(self.data)
if 'content' in data:
content = data['content']
if isinstance(content, list):
content = content[0] # QueryDict wraps even single values to list
data['content'] = ' '.join(content.strip().split())
self.data = data # I do this trick becouse request.POST is immutable
return super(MyForm, self).clean(*args, **kwargs)
UPD: error fix: super(self.__class__, self)
may cause infinite recursion if I use form inheritance :).
UPD: seems still have troubles, and not work correctly.