1

I created a custom user model (following this writeup), and I manage to get the signup and login to work. However, I'm having trouble logging into admin. Specifically, even after "successfully" created a superuser, I'm unable to login to the admin and got error message: "Please enter the correct email address and password for a staff account. Note that both fields may be case-sensitive."

For the sake of completeness, I'm attaching the following code. I know it's a lot but any suggestion would be helpful. Thanks!!

models.py

from django.db import models from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin class UserManager(BaseUserManager): def create_user(self, email, password=None): if not email: raise ValueError('Users must have an email address') user = self.model(email=self.normalize_email(email), ) user.is_active = True user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password): user = self.create_user(email=email, password=password) user.is_admin = True user.is_superuser = True user.save(using=self._db) return user class User(AbstractBaseUser, PermissionsMixin): """ Custom user class. """ email = models.EmailField('email address', unique=True, db_index=True) joined = models.DateTimeField(auto_now_add=True) is_active = models.BooleanField(default=True) is_admin = models.BooleanField(default=False) objects = UserManager() USERNAME_FIELD = 'email' def __str__(self): return self.email def get_full_name(self): # The user is identified by their email address return self.email def get_short_name(self): # The user is identified by their email address return self.email 

custom backend in backends.py

from django.conf import settings from django.contrib.auth.models import check_password from account.models import User class EmailAuthBackend(object): """ A custom authentication backend. Allows users to log in using their email address. """ def authenticate(self, email=None, password=None): """ Authentication method """ try: user = User.objects.get(email=email) if user.check_password(password): return user else: print('Password not correct') except User.DoesNotExist: print('User does not exist') return None def get_user(self, user_id): try: user = User.objects.get(pk=user_id) if user.is_active: return user return None except User.DoesNotExist: return None 

admin.py

from django.contrib import admin from django.contrib.auth.admin import UserAdmin from django.contrib.auth.forms import UserCreationForm, UserChangeForm, ReadOnlyPasswordHashField from .models import User as AuthUser from django import forms class CustomUserCreationForm(UserCreationForm): """ A form for creating new users. Includes all the required fields, plus a repeated password. """ password1 = forms.CharField(label='Password', widget=forms.PasswordInput) password2 = forms.CharField(label='Password Confirmation', widget=forms.PasswordInput) class Meta(UserCreationForm.Meta): model = AuthUser fields = ('email',) def clean_password2(self): #Check that the two password entries match password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError("Passwords do not match.") return password2 def save(self, commit=True): #Save the provided password in hashed format user = super(UserCreationForm, self).save(commit=False) user.set_password(self.cleaned_data["password1"]) if commit: user.save() return user class CustomUserChangeForm(UserChangeForm): password = ReadOnlyPasswordHashField(label="password", help_text="""Raw passwords are not stored, so there is no way to see this user's password, but you can change the password using <a href=\"password/\"> this form</a>.""") class Meta(UserChangeForm.Meta): model = AuthUser fields = ('email', 'password', 'is_active', 'is_superuser', 'user_permissions') def clean_password(self): # Regardless of what the user provides, return the initial value. # This is done here, rather than on the field, because the # field does not have access to the initial value return self.initial["password"] class AuthUserAdmin(UserAdmin): form = CustomUserChangeForm add_form = CustomUserCreationForm list_display = ('email', 'is_superuser') list_filter = ('is_superuser',) fieldsets = ( (None, {'fields': ('email', 'password')}), ('Permissions', {'fields': ('is_active', 'is_superuser')}), ) add_fieldsets = ( (None, { 'classes': ('wide',), 'fields': ('email', 'password1', 'password2', 'is_superuser')} ), ) search_fields = ('email',) ordering = ('email',) filter_horizontal = ('groups', 'user_permissions',) admin.site.register(AuthUser, AuthUserAdmin) 
0

2 Answers 2

1

The attribute that controls access to the admin is is_staff, not is_admin.

If you wanted to keep your current field for whatever reason, you could define an is_staff() method and make it a property.

Sign up to request clarification or add additional context in comments.

Comments

0

Upgrade your Django to 1.9 version. I had resolved this issue using:

$ pip install django==1.9b1 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.