web-dev-qa-db-ja.com

保存する前に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']

私はこれを試しました:

    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']
28
shibly

保存する前にデータに対して何かを行う必要がある場合は、次のような関数を作成します。

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):

そのため、内部でパスワードを暗号化し、暗号化されたパスワードを返します。

というのは:

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

したがって、フォームを有効にすると、パスワードは暗号化されます。

39
Jesus Rodriguez

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()
11
Burhan Khalid

__clean_メソッドをオーバーライドし、 それらのチェック を配置します。そこから_cleaned_data_を変更できます。

例えば:

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

フォームのすべてのフィールドには、Djangoによって自動的に作成されるfield_name_clean()メソッドがあります。このメソッドは、form.is_valid()を実行すると呼び出されます。

5
e-satis

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})
5
Serafim Suhenky

以前のソリューションの問題は、検証が失敗すると機能しないことです。検証を回避するために、インスタンスを使用できます:

_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()
_
0
Özer S.