I am using django custom usermodel with restframework , after registering successfully I am unable to login for normal users.I am able to login via the initial superuser but if I create new superuser ,they are registered successfully but gives error while logging in as when trying with a normal user.
Error
Please enter the correct email and password for a staff account. Note that both fields may be case-sensitive.
For few profiles I also observed following error in admin panel.
invalid password format or unknown hashing algorithm
models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin
from django.db import models
from django.utils import timezone
class UserManager(BaseUserManager):
def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
if not email:
raise ValueError('Users must have an email address')
now = timezone.now()
email = self.normalize_email(email)
user = self.model(
email=email,
is_staff=is_staff,
is_active=True,
is_superuser=is_superuser,
last_login=now,
date_time_onboarded=now,
**extra_fields
)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password, **extra_fields):
return self._create_user(email, password, True, True, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
user = self._create_user(email, password, True, True, **extra_fields)
return user
class AppOnboarding(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True)
product_name = models.CharField(max_length=254, null=True, blank=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=True)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_time_onboarded = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = 'email'
EMAIL_FIELD = 'email'
REQUIRED_FIELDS = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
serializers.py
from rest_framework import serializers
from .models import AppOnboarding
class AppOnboardingSerializer(serializers.ModelSerializer):
class Meta:
model = AppOnboarding
fields = ['email', 'product_name', 'password']
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
app_onboard = AppOnboarding(
email=self.validated_data['email'],
product_name=self.validated_data['product_name']
)
password = self.validated_data['password']
app_onboard.set_password(password)
app_onboard.save()
def save(self):
app_onboard = AppOnboarding(
email=self.validated_data['email'],
product_name=self.validated_data['product_name']
)
password = self.validated_data['password']
app_onboard.set_password(password)
app_onboard.save()
urls.py
from django.urls import path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register('app', views.AppOnboardingView)
urlpatterns = router.urls
views.py
from django.shortcuts import render
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status, viewsets
from .serializers import AppOnboardingSerializer
from .models import AppOnboarding
class AppOnboardingView(viewsets.ModelViewSet):
queryset = AppOnboarding.objects.all()
serializer_class = AppOnboardingSerializer
*settings.py
"""
Django settings for nrn project.
Generated by 'django-admin startproject' using Django 2.2.5.
For more information on this file, see
https://docs.djangoproject.com/en/2.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.2/ref/settings/
"""
# , EMAIL_HOST_USER , EMAIL_HOST_PASSWORD
from .email_info import EMAIL_HOST, EMAIL_PORT
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'mz)6t6hfo*44sz*g)u&2o5!9p9azk!lwuju=*0lp_-c5)m-hj4'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'send',
'apponboarding'
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'nrn.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'nrn.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
EMAIL_HOST = EMAIL_HOST
EMAIL_PORT = EMAIL_PORT
EMAIL_USE_TLS = False
EMAIL_USE_SSL = False
AUTH_USER_MODEL = 'apponboarding.AppOnboarding'
# REST_FRAMEWORK = {
# 'DEFAULT_AUTHENTICATION_CLASSES': [
# 'rest_framework.authentication.SessionAuthentication',
# ],
# }
# AUTHENTICATION_BACKENDS = (
# 'django.contrib.auth.backends.RemoteUserBackend',
# 'django.contrib.auth.backends.ModelBackend',
# )
In your settings you have to mention your custom auth user model if you defined a custom user.
AUTH_USER_MODEL = 'your_custom_account.User'
For permissions you can add the following code to AppOnboarding
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin