tags:

views:

49

answers:

1

How can I clean the data in a form and have the cleaned data redisplayed instead of the submitted data?

There are several fields in my form, and every time the user submits it, it should be redisplayed with the values the user entered. However, some of the fields I would like to clean and update for the user. More specifically, I have a field FriendlyIntegerField(forms.CharField) in which I override to_python to not only call int(str(value)), but also set any negative number to 0 etc. I do not want to redisplay the form with the invalid data and have the user fix it himself (which is how Django wants me to do it).

I don't have a problem cleaning the data and use it for the rest of my view-function, but how can I update the actual form with this data?

By the way, the form does not reflect a structure in my data model, and so inherits from Form, not ModelForm.

Edit:

My Field (in a stripped down version) looks like this:

class FriendlyIntegerField(forms.CharField):
    def to_python(self, value):
        try:
            return str(int(str(value).replace(' ','')))
        except:
            raise forms.ValidationError('some error msg')

My Form (in a stripped down version) looks like this:

class SearchForm(forms.Form):
    price_from = FriendlyIntegerField()
    price_to = FriendlyIntegerField() 

And my view:

def search(request, key):
    if request.method == 'POST':
        form = SearchForm(request.REQUEST)
        if not form.is_valid():
            print "Form not valid"
    else:
        form = SearchForm()
    return render_to_response('path_to_template', {'form' : form}

A: 

If, after you've cleaned your form with is_valid(), you render that cleaned form with your view, rather than redirect to a new page, you'll see the cleaned data in your page.

(If you wanted the user to see this cleaned data and then properly submit it, you could use a hidden field to track whether the form data has already been cleaned, but this isn't without complications...)

stevejalim
Are you sure the cleaned data is supposed to be rendered when the form is redisplayed, and not the original data? I have posted a stripped down version of my code above, and would really appreciate if you could have a look and check if you can see why the cleaned data is not rendered. As an example, if I input a number with a space in it, like "42 43", I would expect it to render as "4243" based on what you are saying here, but it still renders as "42 43"
knatten
Fix it in the clean_foo(self) method and remember to return your cleaned value at the end of it. Hacking to_python is not the appropriate place if you want to clean data (and show the effect of cleaning)
stevejalim
Ok, I changed to using a regular CharField, and do the cleaning in SearchForm.clean_price_from(), which returns the cleaned value. My view is the same as above, except that I log form.cleaned_data['price_from'] right before 'else'. The logged data is cleaned, the redisplayed form is not.
knatten
Also, browsing through Django's source code, it doesn't seem to follow that the cleaned data should be redisplayed. This is my understanding of django/form/forms.py: A bound form has a BoundField, which is initialized from the form's original field. When the BoundField is rendered, the data used as the value is extracted from the datadict in the original field, not from self.cleaned_data. I can not see the original field being updated from self.cleaned_data any place either.
knatten