2012-01-19 20 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'] 

Próbowałem to:Jak mogę zmienić wartość pola formularza Django przed zapisaniem?

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

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

ale mam błąd. Jak mogę zmienić wartość userf.data['password'] i userf.data['passwordrepeat'] przed zapisaniem?

Błąd:

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

Jakiego rodzaju błędu masz? Błąd sprawdzania poprawności, błąd integralności?Zawsze należy opublikować komunikat o błędzie. ZAWSZE. –

+0

Zaktualizowałem błąd, jeszcze raz to zrozumiem. – shibly

+0

Potrzebujemy również tego, co chcemy: ustawić domyślną wartość, ustawić wartość, jeśli nie istnieje, poprawić wartość, jeśli nie jest dobra, itp. Istnieje kilka haczyków w formularzach django. –

Odpowiedz

29

save() Jeśli trzeba coś zrobić, aby dane przed zapisaniem, wystarczy utworzyć funkcję jak:

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

Wszystko, co potrzebne jest do stworzenia funkcja o nazwie ** clean _ *** nameofdata * gdzie nazwaofdata to nazwa pola, więc jeśli chcesz zmodyfikować pole hasła, potrzebujesz:

def clean_password(self): 

jeśli trzeba zmodyfikować passwordrepeat

def clean_passwordrepeat(self): 

Więc wewnątrz tam, po prostu CRIPT hasła i powrócić cripted jeden.

Znaczy:

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

więc kiedy ważna forma, hasło będzie cripted.

+0

Nie rozumiem twojego pytania. Gdzie? Wewnątrz clean_foo otrzymujesz zwykłe hasło i przekształcasz je. –

+2

Chodziło mi o to, gdzie chciałbym stworzyć te funkcje 'def clean_password (self):'? – shibly

+0

O, prawda, w klasie formularza, którą utworzyłeś. –

5

Zastąp _clean metody i umieścić your checks in them. Możesz zmodyfikować stamtąd cleaned_data.

Np:

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

Co pola w formularzu będą miały field_name_clean() sposób utworzony automatycznie przez Django. Ta metoda jest wywoływana, gdy wykonujesz form.is_valid().

+0

Nie mogłem tego zrozumieć. Czy możesz opublikować kompletny kod z wyjaśnieniem. To byłoby pomocne. – shibly

+0

To ModelForm, a nie Form, czy jest dostępne dane czyszczone dla ModelForm? – shibly

+0

Kiedy wywoływana jest funkcja 'clean_passwor (self):'? – shibly

8

Zobacz dokumentację dla metody

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

Jest to jeden rodzaj aktualizacji. Czy można zmienić/zmodyfikować wartość przed zapisaniem? – shibly

5

Będziesz miał problemy, jeśli musisz wypełnić formularz z POST, zmienić wartość pola formularza i ponownie wyświetlić formularz. Oto rozwiązanie dla niego:

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

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

A potem:

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

Miałem podobny problem, gdy mam dwa przyciski przesyłania. Pierwsza tworzy podgląd, a druga to faktyczne przesłanie. Wartość nie przesłanego przycisku zostanie wymazana poprzez utworzenie formularza z danymi POST (naturalnie). Ta metoda doskonale nadaje się do przywracania wartości przycisku bez kliknięcia. – Scott

+0

To jest ładne i elastyczne –

0

Problem z poprzednich rozwiązań jest to, że to nie będzie działać, jeśli uwierzytelnienie nie powiedzie. W celu uniknięcia walidację, można użyć instancji:

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

Ale uważaj, to nie sprawdza is_valid(). Jeśli chcesz to zrobić, możesz utworzyć formularz z nowymi wartościami:

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