1

I am developing a small website with django and I am using the built-in login view. When I register a standard user and then try to login with the right credentials it shows me the login error "please enter a correct username and password". This problem doesn't occurr with the superusers that I created. The can login with the right credentials without any error message showed.

This is the views.py with my registration view.

from django.shortcuts import redirect, render, get_object_or_404
from django.contrib.auth.models import User
from .forms import UserForm

def register_user(request):
    if request.method == "POST":
        form = UserForm(request.POST)
        if form.is_valid():
            user = form.save()
            return redirect('user_profile', pk=user.pk)
    else:
        form = UserForm()
    return render(request, 'interport/register_user.html', {'form':form})

The admin.py:

from django.contrib import admin
from django.contrib.auth.models import User

forms.py:

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
    model = User
    fields = ('first_name', 'last_name', 'email', 'username', 'password',)

urls.py:

from django.conf.urls import url
from django.contrib.auth import views as auth_views
from . import views

urlpatterns = [
    url(r'^accounts/login/$', auth_views.login, name='login'),
    url(r'^logout/$', auth_views.logout, {'next_page': '/'}, name='logout'),
    url(r'^register_user$', views.register_user, name='register_user'),
    url(r'^$', views.home, name='home'),
]

the template for login:

{% extends "interport/base.html" %}
{% block content %}
<div class="container">
  <div class="row">
    <div class="center col s4 offset-s4 card-panel #fff8e1 amber lighten-5">
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
    </div>
  </div>
</div>
{% endblock %}
Artem Bernatskyi
  • 4,185
  • 2
  • 26
  • 35
kensei
  • 13
  • 1
  • 3
  • where are you trying to log in? the django admin view? I'm pretty sure that only superusers have access to the admin view. – deweyredman Jan 06 '17 at 23:01
  • @deweyredman `is_admin` boolean gives a user access to the admin. Superusers have all permissions. But authentication is something else. It is perfectly okay to login a user that does not have access to the admin at all. – allcaps Jan 06 '17 at 23:16

2 Answers2

6

You're saving the new user with a plain text password, but Django will always hash the password before checking for validity.

You need to create your users via User.objects.create_user(), which hashes the password correctly, or use user.set_password() to set the hashed password after creating.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 1
    so @daniel I should modify the view for registration and after: user= form.save() put this line: user.set_password('raw_password') – kensei Jan 06 '17 at 23:15
3

The accepted answer is good and old, however I would advice to put those instructions in the save function of the said form. This way allows you to have a clearer code in your views and an easier maintenance should you change the way the form is handled. you dont have to go back to every function in your views.py where you used that form.

in OP's case, the Form would look like that afterwards:

from django import forms
from django.contrib.auth.models import User

class UserForm(forms.ModelForm):
    class Meta:
    model = User
    fields = ('first_name', 'last_name', 'email', 'username', 'password',)

    def save(self, commit=False):
        instance = super(UserForm, self).save(commit=False) # create but don't save yet
        if commit:
            instance.set_password(instance.password)
            instance.save()
        return instance

There might be more elegant way, but it's been working for me like that.

to have explanation regarding commit=False : Django ModelForm: What is save(commit=False) used for?

sigmal
  • 66
  • 3