2012-01-19 13 views
23
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フォームにはいくつかのフックがあります。 –

答えて

29

のためのマニュアルを参照してください:あなたが必要とするすべては作成することです

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

** clean_ *** nameofdata *という名前の関数の名前のデータはフィールドの名前なので、パスワードフィールドを変更する場合は、

def clean_password(self): 

あなたはpasswordrepeat

def clean_passwordrepeat(self): 

を変更する必要があるのであればそこの内側に、ちょうどあなたのパスワードをCRIPTとcripted 1を返しますが。

私は意味:

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

フォーム、パスワードはcriptedされますので、あなたが有効なとき。

+0

私はあなたの質問を理解していません。どこ? clean_fooの内部では、プレーンなパスワードを取得して変換します。 –

+2

私は 'def clean_password(self):'関数をどこで作成するのですか? – shibly

+0

あなたが作成したフォームクラスの中で、まあまあです。 –

5

オーバーライド_clean方法とyour checks in themを置きます。そこからcleaned_dataを変更することができます。

例えば:フォームで

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

すべてのフィールドはジャンゴによって自動的に作成field_name_clean()メソッドを持つことになります。このメソッドは、form.is_valid()を実行したときに呼び出されます。

+0

私は理解できませんでした。あなたはexplainationで完全なコードを投稿できますか?それは助けになるだろう。 – shibly

+0

FormではなくModelFormが、ModelFormで使用できるcleaned_dataですか? – shibly

+0

'clean_passwor(self):'関数はいつ呼び出されますか? – shibly

8

あなたが保存する前に、データに何かをする必要がある場合は、同じように関数を作成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

5

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

私は2つの送信ボタンがあるのと同様の問題がありました。最初はプレビューを作成し、2番目はプレゼンテーションを作成します。送信されなかったボタンの値は、POSTデータ(自然)を使ってフォームを作成することで一掃されます。このメソッドの作業は、クリックされていないボタンの値を復元するのに完璧です。 – Scott

+0

これは素晴らしく柔軟です –

0

以前の解決策の問題点は、検証が失敗した場合、それは動作しないこと、です。これはis_valid()をチェックしません、

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

しかし、注意してください:検証を避けるために、あなたは、インスタンスを使用することができます。これを行うには、新しい値でフォームをインスタンス化することができます。

# NOT TESTED, NOT SURE IF THIS WORKS... 
form = MyForm(instance=instance) 
if form.is_valid(): 
    form.save() 
関連する問題