Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django can't login after sign up using custom model

So i create a custom model with AbstractUser:

class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
    phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
    phone = models.CharField(validators=[phone_regex], max_length=17, blank=False, null=False) # Validators should be a list
    is_shop = models.BooleanField(default=False)
    products = models.ManyToManyField('Product', blank=True)

    class Meta:
        db_table = "scrape_customuser"
    def save(self, *args, **kwargs):
        if not self.pk: 
            self.set_password(self.password)
        super().save(*args, **kwargs)

and a sign up form

class UserForm(UserCreationForm):
    class Meta:
        model = CustomUser
        fields = ['username', 'email', 'phone', 'password1', 'password2']

my login logic:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

def shop_user_signup(request):
    if request.method == 'POST':
        form = UserForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_shop = True
            user.save()
            login(request, user)
            referring_url = request.POST.get('next', None)
                if  referring_url:
                    return redirect(referring_url)
                else:
                    return redirect('/')
    else:
        form = UserForm()
    return render(request, 'shop_user_signup.html', {'form': form})

The user got created in the database with password got hash to something like this pbkdf2_sha256$600000$TvRyCcSY6eMhnV1i1urh93$aKLqPBrcma5KsuS469crJtS93UI0h+7pduJXeW6ukAU=, is_active=1 and somehow the last login is 2023-11-23 15:49:22.581983 even though the redirect didn’t show username when i have

<li class="nav-item">
    {% if user.is_authenticated %}
        <a class="nav-link" href="{% url 'logout' %}">{{user.username}} | Logout</a>
    {% else %}
        <a class="nav-link" href="{% url 'login' %}">Login</a>
    {% endif %}
</li>

When i try to login in the login page i got the error Please enter a correct username and password. Note that both fields may be case-sensitive. And the admin account can login normally.

>Solution :

Don’t set the password in the model. This will hash the password a second time: once by the form, and once by the model. Indeed, if we look at the BaseUserCreationForm, we see [GitHub]:

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

So omit rehashing it a second time:

class CustomUser(AbstractUser):
    email = models.EmailField(unique=True)
    phone_regex = RegexValidator(
        regex=r'^\+?1?\d{9,15}$',
        message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.",
    )
    phone = models.CharField(
        validators=[phone_regex], max_length=17, blank=False, null=False
    )  # Validators should be a list
    is_shop = models.BooleanField(default=False)
    products = models.ManyToManyField('Product', blank=True)

    class Meta:
        db_table = 'scrape_customuser'

    # no override

You can simplify the view to:

def shop_user_signup(request):
    if request.method == 'POST':
        form = UserForm(request.POST, request.FILES)
        if form.is_valid():
            form.instance.is_shop = True
            user = form.save()
            login(request, user)
            referring_url = request.POST.get('next', None)
                if  referring_url:
                    return redirect(referring_url)
                else:
                    return redirect('/')
    else:
        form = UserForm()
    return render(request, 'shop_user_signup.html', {'form': form})

and in the template, check:

{% if request.user.is_authenticated %}
    <!-- … -->
{% endif %}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading