AUTH_USER_MODEL does not accept sub application

1,183 views
Skip to first unread message

Frankline

unread,
Oct 27, 2014, 2:39:36 AM10/27/14
to django...@googlegroups.com
I am having problems with my custom user model while using Django 1.7.1 and Python 3.4.
I have declared a Custom user model in an apps.users.AuthUser. I then have another application (apps.pets) that will use the AuthUser as a ForeignKey in a Pet model. See below:

class Pet(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL, db_index=True, blank=False, null=False)

This is my scenario:

In my INSTALLED_APPS I have: "apps.users"

If I set AUTH_USER_MODEL="apps.users.AuthUser" the exception is raised when I run 'runserver':
  File "/home/frank/.virtualenvs/myproj/lib/python3.4/site-packages/django/contrib/auth/checks.py", line 12, in check_user_model
    cls = apps.get_model(settings.AUTH_USER_MODEL)
  File "/home/frank/.virtualenvs/myproj/lib/python3.4/site-packages/django/apps/registry.py", line 201, in get_model
    app_label, model_name = app_label.split('.')
ValueError: too many values to unpack (expected 2)


If I set AUTH_USER_MODEL="users.AuthUser" the exception is raised when I run migrate:
  File "/home/frank/.virtualenvs/myproj/lib/python3.4/site-packages/django/db/migrations/state.py", line 89, in render
    model=lookup_model,
ValueError: Lookup failed for model referenced by field pets.Pet.owner: users.AuthUser

Similar issue reported here I guess: https://code.djangoproject.com/ticket/19845


Does this mean that in AUTH_USR_MODEL setting I have to use 'app_label.model_name' instead of 'apps.app_label.model_name.'? Is there a workaround for this?

Collin Anderson

unread,
Oct 27, 2014, 8:44:55 AM10/27/14
to django...@googlegroups.com
Hi Frankline,

Like you said, you need to use 'app_label.model_name' for AUTH_USER_MODEL, instead of 'apps.app_label.model_name'. Django looks at INSTALLED_APPS and knows to add the "apps" prefix when importing.

What's wrong with setting AUTH_USER_MODEL to 'app_label.model_name'?

Collin

Scot Hacker

unread,
Oct 27, 2014, 11:58:36 AM10/27/14
to django...@googlegroups.com
Since the  apps are in an "apps" folder, that folder location will need to be added to the python path. Then Frankline will be able to refer to them throughout the codebase via app_label.model_name rather than apps.app_label.model_name. If you're using virtualenv/virtualenvwrapper, this is easy to do:

add2virtualenv /path/to/custom/apps/directory

./s


Scot Hacker

unread,
Oct 27, 2014, 12:01:26 PM10/27/14
to django...@googlegroups.com


On Monday, October 27, 2014 8:58:36 AM UTC-7, Scot Hacker wrote:

add2virtualenv /path/to/custom/apps/directory



And when its time to deploy, you'll need to do similar on the server, using an equivalent method in the wsgi definition, e.g.:

import os, sys, site

sys.path.append('/path/to/custom/apps/directory') 


./s


Carl Meyer

unread,
Oct 27, 2014, 4:51:39 PM10/27/14
to django...@googlegroups.com
Hi Frankline,
Why is a workaround needed?

Django has the concept of "app label", which is usually the final
component of the app's import path (although in Django 1.7 with
AppConfig it no longer has to be). So for an app whose import path is
"apps.users", its app label is "users". And the format of
AUTH_USER_MODEL (like the format for string model references elsewhere
in Django) is simple "app_label.ModelName", not a full Python import path.

So having "apps.users" in INSTALLED_APPS and "users.User" in
AUTH_USER_MODEL is fully correct and normal; there is no bug there, and
no need for a workaround.

(That said, I do find the whole concept of app-label unfortunate -- why
not just use full import paths and avoid conflicts between "foo.users"
and "bar.users"? -- and especially the use of dotted syntax in
"app_label.ModelName", which looks so much like an import path. But
nevertheless, app labels are a long-standing part of Django legacy which
can't be easily excised.)

Carl

signature.asc

Carl Meyer

unread,
Oct 27, 2014, 4:52:02 PM10/27/14
to django...@googlegroups.com
Please don't do this. There is no good reason to add complexity to the
sys.path required for your site to run. Everything is simpler if you
have a single "root path" for all Python code in your project, and make
all import paths relative to that single filesystem location (which
should generally be the location of `manage.py`).

If you don't want to have to import from "apps.users", then just get rid
of the "apps/" directory and move all the apps in there up one
filesystem level. Django apps aren't special, they're just Python
modules; they can be placed into a logical module hierarchy just like
any other module.

Carl

signature.asc
Reply all
Reply to author
Forward
0 new messages