The least painful and indeed Django-recommended way of doing this is through a OneToOneField(User)
property.
…
If you wish to store information related to User
, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user.
That said, extending django.contrib.auth.models.User
and supplanting it also works...
Some kinds of projects may have authentication requirements for which Django’s built-in User
model is not always appropriate. For instance, on some sites it makes more sense to use an email address as your identification token instead of a username.
[Ed: Two warnings and a notification follow, mentioning that this is pretty drastic.]
I would definitely stay away from changing the actual User class in your Django source tree and/or copying and altering the auth module.
This was added to the documentation when Django 1.7 was released:
Strictly speaking, signal handling and registration code can live anywhere you like, although it’s recommended to avoid the application’s root module and its models module to minimize side-effects of importing code.
In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator, simply import the signals submodule inside ready().
Changed in Django 1.7: Since ready() didn’t exist in previous versions of Django, signal registration usually happened in the models module.
Best practice is to define your handlers in handlers.py in a signals submodule, e.g. a file that looks like:
yourapp/signals/handlers.py:
from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel
@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
pass
The best place to register your signal handler is then in the AppConfig of the app that defines it, using the ready() method. This will look like this:
yourapp/apps.py:
from django.apps import AppConfig
class TasksConfig(AppConfig):
name = 'tasks'
verbose_name = "Tasks"
def ready(self):
import yourproject.yourapp.signals.handlers #noqa
Make sure you're loading your AppConfig by specifying it either directly in your settings.py's INSTALLED_APPS, or in the __init__
of your app. See see the ready() documentation for more information.
Note: If you're providing signals for other apps to listen too as well, put them in the __init__
in your signals module, e.g. a file that looks like:
yourapp/signals/__init__.py
import django.dispatch
task_generate_pre_save = django.dispatch.Signal(providing_args=["task"])
Another app can then listen to your signal by importing and registering it, e.g. from yourapp.signals import task_generate_pre_save
. Separating your signals from your handlers keeps things clean.
Instructions for Django 1.6:
If you're still stuck on Django 1.6 or lower, then you'd do the same thing (define your handlers in yourapp/signals/handlers.py) but rather than using AppConfig, you would load the handlers via the __init__.py of your app, e.g. something like:
yourapp/__init__.py
import signals
This isn't as nice as using the ready() method because it often causes circular import issues.
Best Answer
Apparently, Python is sensitive to the way you import modules. In my case, it wasn't an issue with any of import code inside my blog application but an issue with the INSTALLED_APPS configuration, which I assume is used by Django to do an initial import.
Inside my blog application I was using imports such as:
My settings.py was configured as:
The "mysite" prefix was added because I originally had import path issues when deploying the site. Later I fixed this issue (so it acted the same as the development server) by adding multiple paths in my WSGI script.
Removing the "mysite" prefix from the settings.py fixed the issue: