2012-01-19 5 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 * где nameofdata - это поле, поэтому, если вы хотите изменить поле пароля, вам необходимо:

def clean_password(self): 

, если вам нужно изменить ПарольПовторите

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

О, верно, внутри класса формы, который вы создали. –

5

Override _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

Я не мог понять. Можете ли вы отправить полный код с объяснением. Это было бы полезно. – shibly

+0

Это ModelForm, а не Form, cleaned_data, доступный для ModelForm? – shibly

+0

Когда называется 'clean_passwor (self):' function? – 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

У меня была аналогичная проблема, когда у меня есть две кнопки отправки. Первый создает предварительный просмотр, а второй - фактическое представление. Невысокая величина кнопки будет уничтожена, создав форму с данными POST (естественно). Этот метод отлично подходит для восстановления значения кнопки без клика. – Scott

+0

Это приятный и гибкий –

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() 
Смежные вопросы