Making your Django app ready for custom users

— 2013-05-22 —

In Django 1.5 custom users was introduced. This means that the user model can be swapped for a custom model. How does this affect third-party apps? Foreignkeys and other relations will crash if they point to auth.User. It will raise a exception of the type: AttributeError: Manager isn't available; User has been swapped for 'myapp.CustomUser'

A possible solution

In django-nopassword I tried a some different approaches. I found a solution that worked well in that app. I added a file, called it utils.py, did not find a more suitable name. The code is listed below:

# -*- coding: utf-8 -*-
import django

if django.VERSION >= (1, 5):
    from django.contrib.auth import get_user_model
    User = get_user_model()
else:
    from django.contrib.auth.models import User

Everywhere I use the User model I changed the import to from app_name.utils import User where app_name in this case was django_nopassword.

Testing

To be certain that everything was working correctly with custom user I created some tests and a test app with a custom user. These tests also work nicely on Django 1.4 since AUTH_USER_MODEL is ignored in earlier versions of Django. To make it easier to test with different environments I added it to Travis and added a hook to the Github repository. The travis settings:

language: python

python:
  - "2.6"
  - "2.7"

env:
  - DJANGO_VERSION=1.4
  - DJANGO_VERSION=1.5

install:
  - pip install psycopg2
  - pip install django==$DJANGO_VERSION

script: python setup.py test

before_script:
  - psql -c 'create database django_nopassword;' -U postgres
    django
    customuser