[Fixed]-Not able to authenticate custom user model in Django

2👍

To create a custom user model, extend the AbstractBaseUser model as recommended by django docs and add your custom fields to it.

Also note that due to limitations of Django’s dynamic dependency feature for swappable models, you must ensure that the model referenced by AUTH_USER_MODEL is created in the first migration of its app (usually called 0001_initial); otherwise, you will have dependency issues.

models.py

import uuid

from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.db import models


class CustomUserManager(BaseUserManager):
    def create_user(self, email, password, **kwargs):
        if not email or not password:
            raise ValueError('User must have a username and password')

        user = self.model(
            email=CustomUserManager.normalize_email(email),
            **kwargs
        )

        user.set_password(password)
        user.save()

        return user

    def create_superuser(self, email, password, **kwargs):
        user = self.create_user(email, password, **kwargs)

        user.is_admin = True
        user.is_staff = True
        user.save()

        return user


class User(AbstractBaseUser):
    first_name = models.CharField(max_length=255, null=False)
    last_name = models.CharField(max_length=255, null=False)
    email = models.EmailField(null=False, unique=True)
    is_active = models.BooleanField(default=True)
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)
    is_staff = models.BooleanField(default=False)

    # Add custom fields here
    api_token = models.UUIDField(default=uuid.uuid4, editable=False)
    token_created_date = models.DateTimeField(auto_now_add=True)

    objects = CustomUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def get_full_name(self):
        return self.first_name + " " + self.last_name

    def get_short_name(self):
        return self.first_name

    def has_perm(self, perm, obj=None):
        return self.is_staff

    def has_module_perms(self, app_label):
        return self.is_staff

    def api_token_reset(self):
        self.api_token = models.UUIDField(default=uuid.uuid4, editable=False)

    class Meta:
        ordering = ('created_on',)
        db_table = 'users'

    def __unicode__(self):
        return self.get_full_name()

And add the following code to your settings.py. NOTE- tester is the name of my app

AUTH_USER_MODEL = 'tester.User'

Now run the following commands –

python manage.py makemigrations
python manage.py migrate

Now you should be able to login to the django admin without any problems.

If you want to create a custom login page, in the view check if the user is an admin or not –

views.py

from django.contrib.auth import authenticate, login
from django.contrib.auth.forms import AuthenticationForm
from django.core.urlresolvers import reverse_lazy
from django.http import HttpResponseRedirect
from django.views.generic import FormView


class LoginView(FormView):
    form_class = AuthenticationForm
    template_name = 'login.html'

    def form_valid(self, form):
        username = form.cleaned_data['username']
        password = form.cleaned_data['password']
        user = authenticate(username=username, password=password)

        # Check here if the user is an admin
        if user is not None and user.is_active and user.is_staff:
            login(self.request, user)
            return HttpResponseRedirect(self.success_url)
        else:
            return self.form_invalid(form)

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Login</title>
</head>
<body>
<form method="post">
    {%  csrf_token %}
    {{ form }}
    <input type="submit" value="Submit">
</form>
</body>
</html>

urls.py

from django.conf.urls import url

from .views import LoginView

urlpatterns = [
    url(r'^login/$', LoginView.as_view(), name='login'),
]

-1👍

Dont know how but i added is_active ,is_admin, is_staff ,is_superuser as true is the super user creation function changed is_active to true in create user and added the above specified backends in settings.py and it started working you just have to creat a new superuser and new database with new migrations after all these alterations. it should work…

create superuser function :

 def create_superuser(self,email, user_name, address, password, **other_fields):
        user = self.creat_user(email,user_name,address ,password=password,**other_fields)
        user.is_admin = True
        user.is_active = True
        user.is_staff = True
        user.is_superuser = True
        user.save()

        return user

create user function

class NewUser(AbstractBaseUser,PermissionsMixin):
    alphanumeric = RegexValidator(r'^[0-9a-zA-Z]*$', message='Only alphanumeric characters are allowed.') 
    email = models.EmailField(_('Enter Email'),unique=True)
    user_name = models.CharField(max_length=20, unique=True, validators=[alphanumeric])
    address= models.TextField(_(
        'enter Address'),max_length=500,blank=True)

    is_staff = models.BooleanField(default=False)
    is_admin = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)

    objects =CustomeAccountManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['user_name','address']

    def __str__(self):
        return self.email
👤cipher

Leave a comment