Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.5: Accessing custom user model fields in models.py

I'm working on a Django 1.5 project and I have a custom user model (let's call it CustomUser). Another app (SomeApp) needs to reference this custom user model. For the purposes of ForeignKey and such, the Django documentation says to use

User = settings.AUTH_USER_MODEL 

However, some functions in SomeApp.models need to access what would have formerly been known as User.objects. But User is now a string and not a class, so User.objects fails. The alternative would be

from django.contrib.auth import get_user_model
User = get_user_model()

Which works in other modules, but when I use this in models.py of SomeApp, Django raises an error:

ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)

Any ideas?

EDIT 1 - Traceback:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "...\django-badger\badger\__init__.py", line 7, in <module>
    from badger.models import Badge, Award, Progress
  File "...\django-badger\badger\models.py", line 26, in <module>
    User = get_user_model()
  File "...\lib\site-packages\django\contrib\auth\__init__.py", line 127, in get_user_model
    raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'MyApp.AuthUser' that has not been installed

EDIT 2 - INSTALLED_APPS settings:

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'south',
'MyApp',   # this is where my user model is defined
'SomeApp', # I try to use get_user_model() in this app's models.py; doesn't work.
'social_auth',
)
like image 544
askvictor Avatar asked Jul 04 '13 11:07

askvictor


People also ask

Can you add fields to Django user model?

According to django documentation, you should create a custom user model whenver you start a django project. Because then you will have full control over the fields of the user objects in django, and you can add as many custom fields to the user model as you need and whenever you need.

How do I reference a user model in Django?

Referencing the User model Instead of referring to User directly, you should reference the user model using django.contrib.auth.get_user_model() . This method will return the currently active user model – the custom user model if one is specified, or User otherwise.

How do I use built in user model in Django?

Django allows you to override the default user model by providing a value for the AUTH_USER_MODEL setting that references a custom model. Method 2 – AUTH_USER_MODEL : AUTH_USER_MODEL is the recommended approach when referring to a user model in a models.py file.


3 Answers

I had the same problem just now and here is my 2 cents/solution.

If you want to use custom user model in models.py you'll be using for foreign keys settings.AUTH_USER_MODEL and for model methods you have to use get_user_model() but it has to be inside the method. It won't work outside because of circular import.

from django.conf import settings
from django.contrib.auth import get_user_model

class Event(models.Model):

    recipient = models.ForeignKey(settings.AUTH_USER_MODEL)
    ...

    def get_something(self):

        User = get_user_model()
        u = User.objects.get(id=...)
        ...
like image 170
Freon Avatar answered Oct 31 '22 11:10

Freon


Easy one, I think. I have had so many problems with recursive inclusions and so on... Well, the simplest thing to do, when you add a ForeignKey, is to write it like so:

user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, on_delete=models.CASCADE, verbose_name=_(u"User"))

If you use get_user_model, do not use it like you do. Calling

User = get_user_model()

at the top of the module will try to import your User model, which may, indeed, not have been "installed". Instead, you have several choices:

  • At the top of your module, write

    User = get_user_model # then, you will have to use User() instead of User

  • Write get_user_model() everywhere it's useful. Always in methods or functions, never directly in a model module body.

like image 20
Steve K Avatar answered Oct 31 '22 12:10

Steve K


Make sure your custom User model is not abstract.

like image 3
Vladimir Prudnikov Avatar answered Oct 31 '22 11:10

Vladimir Prudnikov