44
if request.method == 'POST': userf = UsersModelForm(request.POST) username = userf.data['username'] password = userf.data['password'] passwordrepeat = userf.data['passwordrepeat'] email = userf.data['email'] 

I tried this:

 tempSalt = bcrypt.gensalt() password = bcrypt.hashpw(password,tempSalt) passwordrepeat = bcrypt.hashpw(passwordrepeat,tempSalt) userf.data['password'] = password userf.data['passwordrepeat'] = passwordrepeat 

But i got error. How can i change the value of userf.data['password'] and userf.data['passwordrepeat'] before saving?

Error:

AttributeError at /register This QueryDict instance is immutable Request Method: POST Request URL: http://127.0.0.1:8000/register Django Version: 1.3.1 Exception Type: AttributeError Exception Value: This QueryDict instance is immutable Exception Location: /usr/local/lib/python2.6/dist-packages/django/http/__init__.py in _assert_mutable, line 359 Python Executable: /usr/bin/python Python Version: 2.6.6 Python Path: ['/home/user1/djangoblog', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/usr/lib/python2.6/lib-old', '/usr/lib/python2.6/lib-dynload', '/usr/local/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages', '/usr/lib/python2.6/dist-packages/gst-0.10', '/usr/lib/pymodules/python2.6', '/usr/lib/pymodules/python2.6/gtk-2.0'] 
6
  • What kind of error do you have ? Validation error, integrity error ? You must always post the error message. ALWAYS. Commented Jan 19, 2012 at 11:31
  • I have updated the error, see that again to understand. Commented Jan 19, 2012 at 13:21
  • We need what you want to do as well: set a default value, set a value if not value exist, correct a value if it's not good, etc. There are several hooks on django forms. Commented Jan 19, 2012 at 13:46
  • I have updated the original post/question. See that again to understand. Commented Jan 19, 2012 at 14:13
  • It doesn't tell us what you want to do, it tells use what you are doing. What result do you want ? Not at the programming level, at the feature level. Commented Jan 19, 2012 at 14:57

6 Answers 6

62

If you need to do something to the data before saving, just create a function like this in your ModelForm class:

def clean_nameofdata(self): data = self.cleaned_data['nameofdata'] # do some stuff return data 

All you need is to create a function with the name clean_nameofdata where nameofdata is the name of the field, so if you want to modify password field, you need:

def clean_password(self): 

if you need to modify passwordrepeat

def clean_passwordrepeat(self): 

So inside there, just encrypt your password and return the encrypted one.

I mean:

def clean_password(self): data = self.cleaned_data['password'] # encrypt stuff return data 

so when you valid the form, the password would be encrypted.

Sign up to request clarification or add additional context in comments.

4 Comments

I don't understand your question. Where? Inside the clean_foo, you get the plain password and transform it.
I meant where would i create those def clean_password(self): functions?
Oh, true, inside the form class you created.
It should be 'self.cleaned_data['password']' (you forgot the 'ed' in the last code block)
23

See the documentation for the save() method

if request.method == 'POST': userf = UsersModelForm(request.POST) new_user = userf.save(commit=False) username = userf.cleaned_data['username'] password = userf.cleaned_data['password'] passwordrepeat = userf.cleaned_data['passwordrepeat'] email = userf.cleaned_data['email'] new_user.password = new1 new_user.passwordrepeat = new2 new_user.save() 

2 Comments

It's one kind of updating. Is it possible to change/modify the value before saving?
The linked section of the Django docs doesn't work anymore. As of today, the latest version of the framework (5.0) has this feature still working the same way, which is documented here: docs.djangoproject.com/en/5.0/topics/forms/modelforms/…
10

You will have problems if you need to fill form from POST, change any form field value and render form again. Here is solution for it:

class StudentSignUpForm(forms.Form): step = forms.IntegerField() def set_step(self, step): data = self.data.copy() data['step'] = step self.data = data 

And then:

form = StudentSignUpForm(request.POST) if form.is_valid() and something(): form.set_step(2) return render_to_string('form.html', {'form': form}) 

2 Comments

I had a similar problem where I have two submit buttons. The first creates a preview and the second is the actual submission. The not submitted button's value would get wiped out by creating form with the POST data (naturally). This method work's perfectly for restoring the non-clicked button's value.
This is nice and flexible
7

Override _clean methods and put your checks in them. You can modify cleaned_data from there.

E.g:

def clean_password(self): new1 = self.cleaned_data['password'] return new1 

Every fields in the form will have a field_name_clean() method created automatically by Django. This method is called when you do form.is_valid().

5 Comments

I could not understand. Can you post complete code with explaination. That would be helpful.
It's ModelForm, not Form, is cleaned_data available for ModelForm?
When is the clean_passwor(self): function called?
This is the complete code. I added a link to the documentation. It works with any form, including model forms. This function is trigged automatically before the model is saved.
3

In Views:

def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): obj = form.save(commit=False) obj.my_field = 'value' obj.save() 

In Forms:

instance = form.instance instance.user = request.user instance.save() 

But be careful, this does not check is_valid(). If you want to do that, you can instantiate the form with the new values:

# NOT TESTED, NOT SURE IF THIS WORKS... form = MyForm(instance=instance) if form.is_valid(): form.save() 

Comments

0

The original question is "to modify/update a form field value before saving". Some methods above seem to be used after saving. This reference may be useful in solving This QueryDict instance is immutable. You may try the following method

if request.method == 'POST': userf = UsersModelForm(request.POST) ... data = request.POST.copy() # remember old state _mutable = data._mutable # set to mutable data._mutable = True data['password'] = password data['passwordrepeat'] = passwordrepeat # set mutable flag back data._mutable = _mutable userf = UsersModelForm(data) if userf.is_valid(): userf.save() 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.