I am creating a custom django user and I get the following error when trying to use it. The error I get is the following
AppRegistryNotReady: Models aren't loaded yet.
My model
class MyCustomUserManager(BaseUserManager):
def create_user(self, username, email, password=None, **kwargs):
if not username:
raise ValueError("Username must be defined for users")
if not kwargs.get('email'):
raise ValueError("Users must have a valid email")
user = self.model(username=username, email=self.normalize_email(email), **kwargs)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password, **kwargs):
user = self.create_user(username, email, password, **kwargs)
user.is_admin = True
user.save()
class MyCustomUser(AbstractBaseUser):
username = models.CharField(max_length=40, unique=True)
email = models.EmailField(max_length=255, unique=True, verbose_name=_('Email Address'))
date_of_birth = models.DateField(auto_now=False, blank=False, null=False, verbose_name=_("Ημ. Γεννήσεως"))
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
first_name = models.CharField(max_length=40, blank=False, null=False, verbose_name=_("Όνομα"))
last_name = models.CharField(max_length=40, blank=False, null=False, verbose_name=_("Επίθετο"))
friends = models.ManyToManyField('self', related_name="friends")
objects = MyCustomUserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email',]
def get_full_name(self):
return "%s %s" % (self.first_name, self.last_name)
def __unicode__(self):
return self.get_full_name()
class Meta:
verbose_name = _('Χρήστης')
verbose_name_plural = _('Χρήστες')
I have also setup settings file to include my new custom user model.
(inside settings.py)
AUTH_USER_MODEL = 'myapp.MyCustomUserModel'
When logging in the shell trying to use my new user type like this
from django.contrib.auth import get_user_model
user = get_user_model().objects.all()
i get the error above. Is there something wrong with Django 1.7
P.S: I used makemigrations and migrate to make models and I am behind a virtualenv.
Starting in django 1.7 you can't use get_user_model in your models.py files or you'll run into this problem. The details/reason can be seen in referencing the user model
To fix this problem, in your models.py files instead of referencing the custom user model with get_user_model, you need to import the name from settings.
from django.conf import settings
class MyModel(models.Model):
...
user = models.ForeignKey(settings.AUTH_USER_MODEL)
When you fix the problem, it will fix your app as well as your shell.
This post has been here for some time, I have come across this same problem today (using Django shell) and would like to share a quick workaround by writing a custom get_user_model() using import_module.
under one of your models.py:
from django.conf import settings
from importlib import import_module
USER_MODEL = settings.AUTH_USER_MODEL.rsplit('.', 1)
def get_user_model():
models = getattr(import_module(USER_MODEL[0]), 'models')
return getattr(models, USER_MODEL[1])
This works in my local machine (Mac) under Django shell, and I hope this will also work under PyCharm shell.
Related
I have a custom user model in my Django project and when I create an instance of request.user in my views PyCharm doesn't seem to recognize the user instance correctly. The available methods/attributes suggested by PyCharm still point to the built-in Django user model but not to my new one.
Is there any way to set this up properly?
Example:
# settings.py
AUTH_USER_MODEL = 'user.UserProfile'
# models.py custom user model
class UserProfile(AbstractBaseUser, PermissionsMixin):
# Email and name of the user
email = models.EmailField(max_length=255, unique=True)
name = models.CharField(max_length=255)
# Privilege and security booleans
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
email_confirmed = models.BooleanField(default=False)
# Company on whose behalf the user acts on
company = models.ForeignKey('company.Company', on_delete=models.CASCADE, blank=True, null=True)
objects = UserProfileManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
def email_user(self, subject, message, from_email=None, **kwargs):
"""Send mail to user - Copied from original class"""
send_mail(subject, message, from_email, [self.email], **kwargs)
def __str__(self):
return self.email
# views.py
def render_dashboard_benefits(request):
# Get current user instance
current_user = request.user
# Typing...
current_user.company
# Pycharm suggests 'first_name' and 'last_name' depending on the initial user model
# but not e.g. "email" or "company" according to the new user model
return render(request, 'test.html')
Re dudulus answer, this indeed works but raises:
current_user: UserProfile = request.user
so still I think this is an IDE bug?
You can use like this.
current_user: UserProfile = request.user
I am unable to authenticate custom user in django==3.1.3
Here is Custom User Manager:
from django.contrib.auth.base_user import BaseUserManager
from django.utils.translation import ugettext_lazy as _
class CustomUserManager(BaseUserManager):
def create_user(self, username, email, password=None):
if username is None:
raise TypeError(_('Users should have a username.'))
if email is None:
raise TypeError(_('Users should have a Email.'))
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password=None):
if password is None:
raise TypeError(_('Password should not be empty.'))
user = self.create_user(username, email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
Here's the CustomUser model:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser
from .managers import CustomUserManager
class CustomUser(AbstractBaseUser):
username = models.CharField(max_length=255, unique=True, db_index=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = CustomUserManager()
def __str__(self):
return self.email
I have added AUTH_USER_MODEL = 'authentication.CustomUser' in settings.py
(authentication is the app name)
In the shell, if I run these, I get authenticated_user as None:
user = CustomUser.objects.create(email='tejas#gmail.com', username='tejas12', password='tejas12')
authenticated_user = authenticate(email='tejas#gmail.com', username='tejas12', password='tejas12')
However, the User gets created successfully with given details.
Also, check_password returns False:
from django.contrib.auth.hashers import check_password
user.check_password('tejas12') # returns False
On creating a user using python manage.py createsuperuser,
authenticate returns the required user, and
check_password returns True
How should I authenticate the custom users?
In your example, you create the user as a regular Django model which doesn't hash password properly
user = CustomUser.objects.create(email='tejas#gmail.com', username='tejas12', password='tejas12')
create_user method should be used instead
>>> second_user = CustomUser.objects.create_user(email='test#example.com', username='test', password='test_passwd')
>>> second_user.check_password('test_passwd')
True
Authentication uses default backend unless you specify your own and will rely on the USERNAME_FIELD and password
>>> from django.contrib.auth import authenticate
>>> authenticate(email='test#example.com', username='test', password='test_passwd')
>>> authenticate(email='test#example.com', password='test_passwd')
<CustomUser: test#example.com>
I am building an app with multiple roles defined through Django Groups.
I started with a custom user model, defined as below.
I am seeing a weird difference in the groups and permissions use when using a custom user model, like the inheritance is missing something.
I would like to use a custom user model so I don't use username but I also need multiple groups and permissions in my application.
from django.db import models
from django.contrib.auth.models import AbstractUser, AbstractBaseUser, BaseUserManager, PermissionsMixin
import random
import string
from slugify import slugify
# Create your models here.
class MyAccountManager(BaseUserManager):
def create_user(self, email, password=None):
if not email:
raise ValueError("You must have an email address")
user = self.model(
email=self.normalize_email(email),
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
user = self.create_user(
email=self.normalize_email(email),
)
user.set_password(password)
user.is_admin=True
user.is_staff=True
user.is_superuser=True
user.save(using=self._db)
return user
#custom user account model
class User_Account(AbstractUser):
email = models.EmailField(verbose_name='email', max_length=60, unique = True)
date_joined = models.DateTimeField(verbose_name="Date Joined", auto_now_add=True)
last_login = models.DateTimeField(verbose_name="Last Login", auto_now=True)
username = models.CharField(max_length=100, null=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = MyAccountManager()
def __str__(self):
return self.email
When I create a new group with the custom user model, the group gets automatically assigned to all created users. I reproduced this behavior both programmatically and through the Django Admin.
When I use the default user model the group creation doesn't assign groups to all users automatically.
I also discovered that when using a custom user model the Django Admin for the users is not the same (the group and permission assignment fields are incomplete - screenshots below)
Weird incomplete Django Admin interface with groups and permissions missing the available fields
Normal Django Admin interface with group and permission assignment as expected - default user model
I managed to fix the issue in the Admin panel. It seems that it's a visual rendering problem caused by a wrong Admin class.
The error was caused by the following:
filter_horizontal = ()
list_filter = ()
fieldsets = ()
I have actually added the proper parameters in the class above but forgot to comment out/remove these lines. Works properly after commenting them out.
Try removing
filter_horizontal = (),
It worked for me.
I'm using a CustomUser in my model. This is the User Manager.
class UserManager(BaseUserManager):
def create_user(self, email, username, password=None, is_staff=False, is_superuser=False, is_active=False,
is_bot=False, is_mobile_verified=False, is_online=True, is_logged_in=True):
logger = logging.getLogger(__name__)
logger.info("REGULAR user created!")
if not email:
raise ValueError('Email is required')
if not username:
raise ValueError('Username is required.')
email = self.normalize_email(email)
user = self.model(email=email, username=username, is_staff=is_staff, is_superuser=is_superuser,
is_active=is_active, is_bot=is_bot, is_mobile_verified=is_mobile_verified,
is_online=is_online, is_logged_in=is_logged_in)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
logger = logging.getLogger(__name__)
logger.info("SUPER user created!")
return self.create_user(email, username, password=password, is_staff=True, is_superuser=True, is_active=True,
is_bot=False, is_mobile_verified=False, is_online=True, is_logged_in=True)
This is my definition of the custom user model.
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(unique=True, max_length=255)
mobile = PhoneNumberField(null=True)
username = models.CharField(null=False, unique=True, max_length=255)
full_name = models.CharField(max_length=255, blank=True, null=True)
birthday = models.DateField(null=True)
gender = models.CharField(max_length=255, null=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=False)
is_mobile_verified = models.BooleanField(default=False)
is_online = models.BooleanField(default=False)
is_logged_in = models.BooleanField(default=True)
is_bot = models.BooleanField(default=False)
location = models.ForeignKey(Location, on_delete=models.SET_NULL, null=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
#objects = UserManager()
get_user_model().objects.create_user(...)
If I uncomment the line objects = UserManager() then I can run the server but the super users created from the admin backend can't log in.
If I use get_user_model() the code breaks and I get the following error
"AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL
django.core.exceptions.ImproperlyConfigured: AUTH_USER_MODEL refers to model 'bouncer.User' that has not been installed
But in my settings.py I've define auth user model
AUTH_USER_MODEL = 'bouncer.User'
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
What am I doing wrong here?
For anyone reading this in 2020, I suspect the problem is dependency related. I ran into the same error as OP.
Your first two checks should be:
1 - Is the app in the installed apps list in your settings.py?
2 - Is the AUTH_USER_MODEL = "app_name_from_apps_py.model_name" set in settings.py?
This was as far as most of the other responses I read go.
What I didn't realise on reading the docs is that to use get_user_model() you need to have established your model first. Of course, right?!
So above, where OP is using get_user_model(), they are creating a circular dependency.
You cannot use get_user_model() within the class that creates this model.
That error looks like bouncer isn't in your INSTALLED_APPS.
So to clarify, you have to have
bouncer/models.py that contains the User model (or models/__init__.py which imports the model from another file)
'bouncer' in the INSTALLED_APPS list in the settings
AUTH_USER_MODEL = 'bouncer.User' (as you do).
In my case I accidentally pasted in Meta class of my custom user the attribute abstract = True. So it raises this error.
For me this was because I had myapp/models/__init__.py and I tried putting the custom User model definition in myapp/models/user.py, and setting AUTH_USER_MODEL = myapp.User. Moving the custom User model definition into myapp/models/__init__.py fixed it. I was unable to import it in __init__.py; I had to move the definition there.
Make sure that you register your model in admin.py and not in models.py
# admin.py
from django.contrib.auth.admin import UserAdmin
admin.site.register(YourUser, UserAdmin)
This solved the problem for me.
Never put custom user model and additional models containing links to user model in one models.py file in one app. This can be a matter of that error.
Bad idea leading to that error:
# customUserModel/models.py
from django.contrib.auth.models import AbstractUser
from django.conf import settings
class User(AbstractUser):
pass
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
some_field = models.CharField(max_length=25)
This is a good idea:
# customUserModel/models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
# additionalUserProfile/models.py
from django.conf import settings
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
some_field = models.CharField(max_length=25)
#settings.py
AUTH_USER_MODEL = 'customUserModel.User'
Try shifting the position of the bouncer app in your INSTALLED APPS, this worked for me.
For some reason the import from django.contrib.auth.backends import BaseBackend caused this problem. I suspect that BaseBackend tries to use the user model, but can't because it's defined further down the file. However if you define your model BEFORE that import then it'll work just fine.
I'm aware this is an old question but I struggled with this issue for two days before finding my mistake, which was failing to follow the models organization in the Django Models docs.
I would have just commented on #5fec's answer, but I don't have the reputation yet. My answer is similar to his, except importing the model in models/__init__.py worked for me. I had neglected the __init__.py file entirely.
If you have the AUTH_USER_MODEL = <app_name>.<user_model> correctly written, and you have your '<app_name>', in your INSTALLED_APPS list, but you're still getting this error, it's possible that your <custom_user> model (e.g. User) is in the wrong place.
It needs to be defined in either:
<app_name>.models.py
OR
<app_name>/models/<arbitrary_name>.py AND there is an <app_name>/models/__init__.py that contains the line from .<arbitrary_name> import <custom_user>
try importing from django.db import models only after importing from django.contrib.auth.models import AbstractUser
I am tying to build a custom user model in a Django app, instead of using the built-in one.
models.py
from django.contrib.auth.models import AbstractBaseUser
from django.db import models
from django.contrib.auth.models import BaseUserManager
class AccountManager(BaseUserManager):
def create_user(self, email, password=None, **kwargs):
if not email:
raise ValueError('Users must have a valid email address.')
if not kwargs.get('username'):
raise ValueError('Users must have a valid username.')
account = self.model(
email=self.normalize_email(email),
username=kwargs.get('username')
)
account.set_password(password)
account.save()
return account
def create_superuser(self, email, password, **kwargs):
account = self.create_user(email, password, **kwargs)
account.is_admin = True
account.save()
return account
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
def __unicode__(self):
return self.email
def get_full_name(self):
return ' '.join([self.first_name, self.last_name])
def get_short_name(self):
return self.first_name
When I run the python manage.py makemigrations commands, I get the following error:
You are trying to add a non-nullable field 'password' to account
without a default; we can't do that (the database needs something to
populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Note, I have added this in settings.py
AUTH_USER_MODEL = 'authentication.Account'
The app is called authentication btw.
How do I fix this? Thanks
The error you're getting is from the database. You can't create a non-nullable column without a default value when there are already rows for that column.
You would either need to set a default for the password field or delete all the users you already have in that table before running this migration.