Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow blank password fields on User model when updating profile in Django

Edited to include code

class UserForm(UserCreationForm):

    def __init__(self, *arg, **kw):
        super(UserForm, self).__init__(*arg, **kw)

        # re-order so email appears last on this form
        email_field = self.fields.pop('email')
        self.fields['email'] = email_field


    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email')

I have a form were users can update their profile details.

Users can optionally update their passwords but it's not required in order to update other profile fields.

The problem is my validations are kicking in when the password and password confirmation fields are blank.

The User models Password field I believe is a required=True and blank=False field so I need a way of simply ignoring blank input from forms when validating on this model.

The User model is the one that ships with Django:

from django.contrib.auth.models import User

Thanks

like image 755
Ashley Avatar asked Dec 18 '12 11:12

Ashley


1 Answers

UserCreationForm is intended to be used for creation. It's better to create a new ModelForm than using this one.

class UserUpdateForm(forms.ModelForm):
    # Feel free to add the password validation field as on UserCreationForm
    password = forms.CharField(required=False, widget=forms.PasswordInput)

    class Meta:
        model = User
        # Add all the fields you want a user to change
        fields = ('first_name', 'last_name', 'username', 'email', 'password') 

    def save(self, commit=True):
        user = super(UserUpdateForm, self).save(commit=False)
        password = self.cleaned_data["password"]
        if password:
            user.set_password(password)
        if commit:
            user.save()
        return user

Or if you want to subclass the UserCreationForm which I doesn't recommend. You can do this :

class UserForm(UserCreationForm):
    password1 = forms.CharField(label=_("Password"), required=False
                            widget=forms.PasswordInput)
    password2 = forms.CharField(label=_("Password confirmation"),
                            widget=forms.PasswordInput, required=False)
    class Meta:
        model = User
        fields = ('first_name', 'last_name', 'username', 'email')

    def save(self, commit=True):
        user = super(UserUpdateForm, self).save(commit=False)
        password = self.cleaned_data["password"]
        if password:
            user.set_password(password)
        if commit:
            user.save()
        return user

I recommend you to use a simple

class UserUpdateForm(forms.ModelForm):       
    class Meta:
        model = User
        # Add all the fields you want a user to change
        fields = ('first_name', 'last_name', 'username', 'email') 

For passwords changing there's another dedicated form that your can use which is django.contrib.auth.forms.SetPasswordForm since changing the password is a different process from updating user informations

like image 114
Anas Avatar answered Oct 14 '22 15:10

Anas