如何更改保存之前Django的表单字段的值?

问题描述:

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

我尝试这样做:如何更改保存之前Django的表单字段的值?

tempSalt = bcrypt.gensalt() 
    password = bcrypt.hashpw(password,tempSalt) 
    passwordrepeat = bcrypt.hashpw(passwordrepeat,tempSalt) 

    userf.data['password'] = password 
    userf.data['passwordrepeat'] = passwordrepeat 

但我得到的错误。我怎样才能在保存之前改变userf.data['password']userf.data['passwordrepeat']价值?

错误:

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'] 
+0

你有什么样的错误?验证错误,完整性错误?您必须始终发布错误消息。总是。 –

+0

我已更新错误,请再次参阅以了解。 – shibly

+0

我们需要你想做的事情:设置一个默认值,如果不存在值,则设置一个值,如果值不好,则更正一个值等。在Django表单中有几个钩子。 –

文档如果你需要在保存前需要做一些数据,只需创建一个功能,如:

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

所有你需要的是创造一个函数名称为** clean _ *** nameofdata *其中nameofdata是该字段的名称,所以如果要修改密码字段,则需要:

def clean_password(self): 

,如果你需要修改passwordrepeat

def clean_passwordrepeat(self): 

所以里面就有,只是CRIPT您的密码,并返回一个cripted。

我的意思是:

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

所以当你有效的形式,密码会被cripted。

+0

我不明白你的问题。哪里?在clean_foo里面,你得到了简单的密码并对其进行了转换。 –

+2

我的意思是在哪里创建那些'def clean_password(self):'functions? – shibly

+0

哦,真的,在你创建的表单类中。 –

覆盖_clean方法,并把your checks in them。您可以从那里修改cleaned_data

E.g:

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

在表单字段的每个将具有由Django的自动创建的field_name_clean()方法。当您执行form.is_valid()时会调用此方法。

+0

我听不懂。你可以发布完整的代码与解释。这将有所帮助。 – shibly

+0

它是ModelForm,而不是Form,是Cleaning_data可用于ModelForm? – shibly

+0

什么时候调用了'clean_passwor(self):'函数? – shibly

请参阅save()方法

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() 
+3

这是一种更新。是否可以在保存前更改/修改值? – shibly

,如果你需要从POST填写表格,更改任何表单字段值,并再次渲染形式您将有问题。 下面是它的解决方案:

class StudentSignUpForm(forms.Form): 
    step = forms.IntegerField() 

    def set_step(self, step): 
    data = self.data.copy() 
    data['step'] = step 
    self.data = data 

然后:

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

我有一个类似的问题,我有两个提交按钮。第一个创建预览,第二个是实际提交。通过使用POST数据创建表单(自然),未提交的按钮的值将被清除。此方法非常适合恢复未点击的按钮的值。 – Scott

+0

这很好,很灵活 –

与以前的解决方案的问题是,如果验证失败,将无法正常工作。为了避免验证,您可以使用如下实例:

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

但是要小心,这不检查is_valid()。如果你想这样做,你可以用新值来实例化表单:

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