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

ho provato questo:Come posso modificare un valore del campo modulo Django prima di salvare?

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

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

ma ho ottenuto l'errore. Come posso modificare il valore di userf.data['password'] e userf.data['passwordrepeat'] prima di salvare?

Errore:

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

Che tipo di errore hai? Errore di convalida, errore di integrità?È sempre necessario inviare il messaggio di errore. SEMPRE. –

+0

Ho aggiornato l'errore, rivedilo per capire. – shibly

+0

Abbiamo bisogno di ciò che vuoi fare: imposta un valore predefinito, imposta un valore se non esiste un valore, correggi un valore se non è buono, ecc. Esistono diversi hook sui moduli django. –

risposta

29

Se avete bisogno di fare qualcosa per i dati prima di salvare, basta creare una funzione come:

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

Tutto ciò che serve è quello di creare un funzione con il nome ** clean _ *** nameofdata * dove nameofdata è il nome del campo, quindi se si desidera modificare il campo della password, è necessario:

def clean_password(self): 

se è necessario modificare passwordrepeat

def clean_passwordrepeat(self): 

Quindi là dentro, solo cripta la password e tornare quello criptato.

voglio dire:

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

modo che quando si valida la forma, la password sarebbe criptato.

+0

Non capisco la tua domanda. Dove? All'interno di clean_foo, ottieni la semplice password e la trasformi. –

+2

Intendevo dove avrei creato quelle 'def clean_password (self):' funzioni? – shibly

+0

Oh, vero, all'interno della classe del modulo che hai creato. –

5

Override _clean metodi e mettere your checks in them. È possibile modificare cleaned_data da lì.

es:

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

Ogni campi del modulo avrà un metodo field_name_clean() creata automaticamente da Django. Questo metodo viene chiamato quando si esegue form.is_valid().

+0

Non ho potuto capire. Puoi pubblicare un codice completo con spiegazioni. Sarebbe utile. – shibly

+0

È ModelForm, non Form, clean_data disponibile per ModelForm? – shibly

+0

Quando viene chiamata la funzione 'clean_passwor (self):'? – shibly

8

vedere la documentazione per il save() metodo di

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

È un tipo di aggiornamento. È possibile modificare/modificare il valore prima di salvare? – shibly

5

Si avranno problemi se è necessario compilare il modulo da POST, modificare nuovamente qualsiasi valore del campo modulo e modulo di rendering. Ecco soluzione per esso:

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

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

E poi:

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

Ho avuto un problema simile in cui ho due pulsanti di invio. Il primo crea un'anteprima e il secondo è l'effettiva presentazione. Il valore del pulsante non inviato verrebbe cancellato creando un modulo con i dati POST (naturalmente). Questo metodo funziona perfettamente per ripristinare il valore del pulsante non cliccato. – Scott

+0

Questo è bello e flessibile –

0

Il problema con le soluzioni precedenti è, che non funziona se la convalida non riesce. Al fine di evitare la convalida, è possibile utilizzare l'istanza:

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

Ma attenzione, questo non controlla is_valid(). Se vuoi farlo, puoi istanziare il modulo con i nuovi valori:

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