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

yo probamos este:¿Cómo puedo cambiar el valor de un campo de formulario de Django antes de guardarlo?

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

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

pero me dio error. ¿Cómo puedo cambiar el valor de userf.data['password'] y userf.data['passwordrepeat'] antes de guardar?

error:

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

¿Qué tipo de error tiene? Error de validación, error de integridad?Siempre debe publicar el mensaje de error. SIEMPRE. –

+0

He actualizado el error, veo eso de nuevo para entender. – shibly

+0

También necesitamos lo que usted quiere hacer: establecer un valor predeterminado, establecer un valor si no existe el valor, corregir un valor si no es bueno, etc. Hay varios enganches en los formularios de django. –

Respuesta

29

Si tiene que hacer algo con los datos antes de guardar, basta con crear una función como:

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

Todo lo que necesita es crear una función con el nombre ** clean _ *** nameofdata * donde nameofdata es el nombre del campo, por lo que si desea modificar el campo de contraseña, necesita:

def clean_password(self): 

si necesita modificar passwordrepeat

def clean_passwordrepeat(self): 

Así que allí dentro, simplemente CRIPT su contraseña y devolver el cripted.

quiero decir:

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

lo que cuando se forma válida, la contraseña se cripted.

+0

No entiendo tu pregunta. ¿Dónde? Dentro de clean_foo, obtienes la contraseña simple y la transformas. –

+2

Quería decir dónde crearía esas funciones 'def clean_password (self):'? – shibly

+0

Oh, cierto, dentro de la clase de formulario que ha creado. –

5

Anulación _clean métodos y poner your checks in them. Puede modificar cleaned_data desde allí.

por ejemplo:

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

Cada campos del formulario tendrá un método field_name_clean() creado automáticamente por Django. Se llama a este método cuando lo haces form.is_valid().

+0

No pude entender. ¿Puedes publicar un código completo con explicación? Eso sería útil. – shibly

+0

¿Es ModelForm, no Formulario, clean_data disponible para ModelForm? – shibly

+0

¿Cuándo se llama a la función 'clean_passwor (self):'? – shibly

8

Consulte la documentación de la save() método

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

Es un tipo de actualización. ¿Es posible cambiar/modificar el valor antes de guardar? – shibly

5

Tendrá problemas si necesita completar el formulario de POST, cambiar el valor de cualquier campo de formulario y presentar el formulario de nuevo. Aquí es solución para ello:

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

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

Y luego:

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

Tuve un problema similar cuando tengo dos botones de envío. El primero crea una vista previa y el segundo es la presentación real. El valor del botón no enviado se borrará creando un formulario con los datos POST (naturalmente). Este método funciona perfectamente para restaurar el valor del botón sin hacer clic. – Scott

+0

Esto es agradable y flexible –

0

El problema con las soluciones anteriores es que no va a funcionar si falla la validación. Con el fin de evitar la validación, puede utilizar la instancia:

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

Pero cuidado, esto no comprueba is_valid(). Si desea hacer eso, puede crear una instancia del formulario con los nuevos valores:

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