Django : Can I use CreateView to create a User object where User is just Django's built in User model?
Asked Answered
W

1

5

I am trying to create a simple user login system where a user gets to sign up on one page and then use those credentials to login to the website on another page. Here's my sign-up and login views:

class SignupView(CreateView):
    model = User
    form_class = SignupForm
    template_name = 'journal_app/signup.html'
    success_url = reverse_lazy('home')

class LoginUserView(LoginView):
    template_name = 'journal_app/login.html'

As you can see I'm using the CreateView to create User objects. After the user signs up I can see that the record is successfully updated in the Users group in my Admin console. The problem is that when I try to login, it always throws me a username/password don't match error. Any ideas what could be the reason? I am a beginner at Django so it could be something pretty simple.

SignupForm-

class SignupForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'username', 'password']
        widgets = {
            'password': forms.PasswordInput()
        }
Willin answered 21/7, 2020 at 20:35 Comment(2)
Yes, why would that not be possible. The SignupForm should however hash the password. Can you share this Form?Alathia
@WillemVanOnsem Added the editWillin
A
6

The problem is that you need to hash the password. Django stores a hash of the password [Django-doc]. If you make a custom user model, you should normally implement a UserManager [Django-doc] as well. This takes a password, and will hash it, for examply by calling a method .set_password(…) [Django-doc]. This method will then hash the password.

You thus can rewrite the form to save the user with:

class SignupForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'username', 'password']
        widgets = {
            'password': forms.PasswordInput()
        }

    def save(self, commit=True):
        user = super().save(commit=False)
        user.set_password(self.cleaned_data['password'])
        if commit:
            user.save()
        return user
Alathia answered 21/7, 2020 at 20:55 Comment(4)
Your solution works perfectly thanks a ton! Just had one query. Why use the 'if commit:' condition?Willin
@Vaibhav: because it should be compatible with the basic save method of a ModelForm. If you specify .save(commit=False), it should not save the object to the database.Alathia
Hey, @WillemVanOnsem, in this case, do I have to create a particular form in order to effectivelly save a new user? I'm using almost the exact same code for the SignUpView class, except for the form_class attribute, which I have a fields attribute instead, with username, email and password.Sulphurate
@101is5: yes because passwords are hashed: that is what .set_password is doing.Alathia

© 2022 - 2024 — McMap. All rights reserved.