Search code examples
djangodjango-formspasswordsdjango-users

Password not saving when creating user


I know there are hundreds of posts about that topic but, in all of them, there is something slightly different from my own program and I can't adapt it to my program because the Django way of handling password is such a mess that I understand nothing. A little help would be greatly appreciated, I thank you in advance.

So, when a new user registers, everything works perfectly but, somehow, the password is not saved in the database. When I go to the admin interface, it tells me that the password format is invalid or the hashag function is not known.

Here is my code :

Forms.py

class InscriptionForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email', 'password']
        widgets = {'username': forms.TextInput(attrs={'class': 'form-control'}),
                    'first_name': forms.TextInput(attrs={'class': 'form-control'}),
                    'last_name': forms.TextInput(attrs={'class': 'form-control'}),
                    'email': forms.EmailInput(attrs={'class': 'form-control'}),
                    'password': forms.PasswordInput(attrs={'class': 'form-control'})}

    def clean_password(self):
        password = self.cleaned_data['password']
        try:
            validate_password(password, user=self)
        except forms.ValidationError:
            self.add_error('password', password_validators_help_texts())

        return password

Views.py

def inscription(request):
    if request.method == "POST":
        form = InscriptionForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
            login(request, new_user)
            request.session['is_connected'] = True
            return redirect(inscription_suite)
    else:
        form = InscriptionForm()

    return render(request, 'inscription/inscription.html', {'form': form})

I already tried modifying the view like this :

def inscription(request):
    if request.method == "POST":
        form = InscriptionForm(request.POST)
        if form.is_valid():
            new_user = form.save(commit=False)
            new_user.password = make_password(form.cleaned_data['password'])
            authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
            login(request, new_user)
            new_user.save()
            request.session['is_connected'] = True
            return redirect(inscription_suite)
    else:
        form = InscriptionForm()

    return render(request, 'inscription/inscription.html', {'form': form})

But it raises the following error ValueError at /inscription Cannot force an update in save() with no primary key.

Can someone help me please ?

Thanks in advance !


Solution

  • You must save password using set_password().

    def inscription(request):
        if request.method == "POST":
            form = InscriptionForm(request.POST)
            if form.is_valid():
                new_user = form.save(commit=False)
                password = form.cleaned_data['password'] # get password
                new_user.set_password(password) # set the password
                new_user.save() # save the user
                authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'],)
                login(request, new_user)
                request.session['is_connected'] = True
                return redirect(inscription_suite)
        else:
            form = InscriptionForm()
    
        return render(request, 'inscription/inscription.html', {'form': form})