[Django]-Change a form value before validation in Django form

13👍

Probably not the Django way but based on https://stackoverflow.com/a/17304350/2730032 I’m guessing the easiest way to change your form value before validation is to do something like the following:

def search_packages_view(request):
    if request.method == 'POST'
        updated_request = request.POST.copy()
        updated_request.update({'price': NEW_PRICE})
        search_packages_form = SearchPackagesForm(updated_request)
        if search_packages_form.is_valid():
             # You're all good

This works but I’d be interested if anyone has another way that seems more in line with Django, or if there isn’t: then an explanation about why.

👤Ixio

2👍

My solution is build on an earlier proposal. It is a working solution, which can be used in several cases.

@Milad Khodabandehloo
had a tricky solution to solve the problem.

changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)

as @The EasyLearn Academy commented: it does not allow you to access actual data submitted in form.

This is because the request.POST is immutable.

But there is a solution to the problem – just have to be more tricky.

This solution is only good if a reference to the object is enough for the certain cause. It leaves the object itself the same.

# write object to variable (data)
data = request.POST

# set to mutable
data._mutable = True

# modify the values in data 
data[modified_field] = new_value

# set mutable flag back (optional)
data._mutable = False

Hope it’s useful!

👤sipi09

1👍

one trick for what you want is to do it like this:

changed_data = dict(request.POST)
changed_data['price'] = NEW_PRICE
search_packages_form = SearchPackagesForm(data = changed_data)

0👍

form.is_valid() runs through your form’s (and model’s in case of a ModelForm) clean method’s, returning True or False

If you plan on changing form data you can do it within the general clean method or at field level, e.g.

class YourForm(DerivingClass):
    # regular stuff

    def clean_<ATTR>(self):
        # here
        return self.cleaned_data

    def clean(self):
        # or here
        return super(YourForm, self).clean()

Leave a comment