web-dev-qa-db-fra.com

Comment puis-je changer une valeur de champ de formulaire Django avant d'enregistrer?

if request.method == 'POST':
    userf = UsersModelForm(request.POST)
    username = userf.data['username']
    password = userf.data['password']
    passwordrepeat = userf.data['passwordrepeat']
    email = userf.data['email']

J'ai essayé ceci:

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

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

Mais j'ai une erreur. Comment puis-je changer la valeur de userf.data['password'] et userf.data['passwordrepeat'] avant d'enregistrer?

Erreur:

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

Si vous devez faire quelque chose aux données avant de les enregistrer, créez simplement une fonction comme:

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

Tout ce dont vous avez besoin est de créer une fonction avec le nom ** clean _ *** nameofdata * où nameofdata est le nom du champ, donc si vous souhaitez modifier le champ du mot de passe, vous avez besoin de:

def clean_password(self):

si vous devez modifier passwordrepeat

def clean_passwordrepeat(self):

Donc, à l'intérieur, cryptez simplement votre mot de passe et renvoyez-le crypté.

Je veux dire:

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

donc lorsque vous validez le formulaire, le mot de passe est crypté.

39
Jesus Rodriguez

Voir la documentation de la méthode 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

Remplacez les méthodes _clean Et mettez vos chèques dedans . Vous pouvez modifier cleaned_data À partir de là.

Par exemple:

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

Tous les champs du formulaire auront une méthode field_name_clean() créée automatiquement par Django. Cette méthode est appelée lorsque vous effectuez form.is_valid().

5
e-satis

Vous rencontrerez des problèmes si vous devez remplir le formulaire à partir de POST, modifier toute valeur de champ de formulaire et restituer le formulaire. Voici la solution:

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

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

Puis:

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

Le problème avec les solutions précédentes est que cela ne fonctionnera pas si la validation échoue. Afin d'éviter la validation, vous pouvez utiliser l'instance:

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

Mais attention, cela ne vérifie pas is_valid(). Si vous voulez le faire, vous pouvez instancier le formulaire avec les nouvelles valeurs:

# NOT TESTED, NOT SURE IF THIS WORKS...
form = MyForm(instance=instance)
if form.is_valid():
    form.save()
0
Özer S.