There are some pitfalls when you need to create and login users manually in Django. Let's create a user first:
def view_handler(request):
username = request.POST.get('username', None)
password = request.POST.get('username', None)
Note that request.POST.get('username', None)
should be used instead of request.POST['username']
. If the later is used, you will get this error:
MultiValueDictKeyError
Once the username and password are extracted, let's create the user
User.objects.create(username=username, password=password, email=email) # DON'T DO THIS
The above code is wrong. Because when create
is used instead of create_user
, the user's password is not hashed. You will see the user's password is stored in clear text in the database, which is not the right thing to do.
So you should use the following instead:
User.objects.create_user(username=username, password=password, email=None)
What if you want to test if the user you are about to create has already existed:
user, created = User.objects.get_or_create(username=username, email=None)
if created:
user.set_password(password) # This line will hash the password
user.save() #DO NOT FORGET THIS LINE
get_or_create
will get the existing user or create a new one. Two values are returned, an user object and a boolean flag created
indicating whether if the user created is a new one (i.e. created = True) or an existing one (i.e. created = False)
It is import to not forget including user.save()
in the end. Because set_password
does NOT save the password to the database.
Login
Now a user has been created successfully, the next step is to login.
user = authenticate(username=email, password=password)
login(request, user)
authenticate()
only sets user.backend
to whatever authentication backend Django uses. So the code above is equivlent to:
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
Django's documentation recommends the first way of doing it. However, there is an use case for the second approach. When you want to login an user without a password:
username = self.request.GET.get('username')
user = User.objects.get(username=username)
user.backend = 'django.contrib.auth.backends.ModelBackend'
login(request, user)
The is used when security isn't an issue but you still want to distinguish between who's who on your site.
So to sum up the code above, here is the view_handler that manually create and login an user:
def view_handler(request, *args, **kwargs):
email = request.POST.get('email', None)
password = request.POST.get('password', None)
if email and password:
user, created = User.objects.get_or_create(username=email,
email=email)
if created:
user.set_password(password)
user.save()
user = authenticate(username=email, password=password)
login(request, user)
return HttpResponseRedirect('where_ever_should_be_redirect_to')
else:
# return error or redirect to login page again