Automatical superuser creation with Django

Published September 4, 2008

I delete and sync my database fairly often during development with Django because the "syncdb" command will not alter the table in the database after, for example, adding a new field to the corresponding model.

The problem I have with this is typing in the same data for a superuser over and over again. It's a very repetitive task, so I was grateful when I heard this tip from my co-worker Sebastian today.

Superuser from fixture

We're going to automatically load the superuser from a fixture. To do this, dump the data of the auth module into a fixture called "initial_data.json":

./manage.py dumpdata --indent=2 auth > initial_data.json

You'll see that along the superuser that you've already created during the usual "syncdb" execution, a few other credentials got dumped. Since we only need the data for the superuser, delete the irrelevant stuff. The file should look like this:

[
  {
    "pk": 1, 
    "model": "auth.user", 
    "fields": {
      "username": "arthur", 
      "first_name": "", 
      "last_name": "", 
      "is_active": true, 
      "is_superuser": true, 
      "is_staff": true, 
      "last_login": "2008-09-04 14:25:29", 
      "groups": [], 
      "user_permissions": [], 
      "password": "sha1$fooobar123", 
      "email": "arthur@arthurkoziel.com", 
      "date_joined": "2008-09-04 14:25:29"
    }
  }
]

The fixture called "initial_data.json" will automatically get loaded by Django every time you execute the "syncdb" command.

Delete your database and try to run the "syncdb" command with the "--noinput" option passed (it will prevent the script to go into interactive mode):

./manage.py syncdb --noinput

There shouldn't be a prompt for a superuser and you should see a message at the end of the output indicating that your fixture was loaded.

Admin login

Not having to create a superuser is great, but if you're working a lot with Django's contrib.admin application, you'll need to log-in again every time you sync the database and load the user fixture. Another repetitive task that can be eliminated:

After logging in into the admin backend, dump the data of the "session" table into stdout:

./manage.py dumpdata --indent=2 sessions

Copy the dictionary containing the session for your superuser and append it to the list in "inital_data.json" like this:

[
  {
    "pk": 1, 
    "model": "auth.user", 
    "fields": {
      "username": "arthur", 
      "first_name": "", 
      "last_name": "", 
      "is_active": true, 
      "is_superuser": true, 
      "is_staff": true, 
      "last_login": "2008-09-04 14:25:29", 
      "groups": [], 
      "user_permissions": [], 
      "password": "sha1$foobarbarfoo", 
      "email": "arthur@arthurkoziel.com", 
      "date_joined": "2008-09-04 14:25:29"
    }
  },
  {
    "pk": "9aadfe1de61b0937fasd684221f03", 
    "model": "sessions.session", 
    "fields": {
      "expire_date": "2008-10-20 14:34:59", 
      "session_data": "foobar123"
    }
  }
]

You might want to increase the "expire_date" a little bit, so that your session won't expire.

Now everytime you delete and sync your database (remember to pass "--noinput"), Django will automatically load the superuser and it's associated session from the fixture. You won't have to manually type in the data for the user and log-in into the backend everytime anymore.

Comments

Jannis Leidel on September 4, 2008
Holy crap, that's useful. I never thought of that.. jeez.

Reply

Aidas Bendoraitis on September 5, 2008
I am also using the same technique for developing and testing one of my projects. But rather I dump all data from all tables into a fixture.

Reply

Metin on September 5, 2008
Incredible! Thanks for sharing. Until there's some sort of "usable" migrations for Django, I'm gonna stick with this method of local development.

Reply

Jean-Philippe Bougie on September 6, 2008
I think a better technique would be to use the ./manage.py reset [app] command, which will only destroy the data of the apps you're developing, and not of the contrib stuff. As long as you don't touch the user data model, it should be a simpler solution. ./manage sqlreset [app] can be used to check what will be executed prior to doing it

Reply

Martin on September 6, 2008
Really nice. Until now I always used "raw sql" fixtures, without the session thing. Will use this from now on. :)

Reply

D3f0 on September 7, 2008
I've made a script that instead of syncdb. Basically it does the same thing. import os import sys sys.path.append('..') SUPERUSER_DATA = { 'username':'admin', 'email':'admin@admin.com', 'password': 'admin' } os.system('rm -rf db/*') # remove Sqlite files, we store SQlite dbs in ./db os.system('python manage.py syncdb --noinput') os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' from django.contrib.auth.create_superuser import createsuperuser createsuperuser(**SUPERUSER_DATA)

Reply

Jiri Barton on September 18, 2008
A brilliant idea it is. Let me extend it a bit further. Create an empty application "superuser" and put your dump there. Include this application in your settings:<br /><br /> <pre> mkdir -p superuser/fixtures touch superuser/__init__.py superuser/models.py ./manage dumpdata auth >superuser/fixtures/initial_data.json <pre><br /> Add 'superuser' to the list of your INSTALLED_APPS in your settings.py. <i>syncdb --noinput</i> will install the fixture automatically.

Reply

Jiri Barton on September 18, 2008
My answer is a mess. I have posted it on my blog with better formatting: http://lurkingideas.net/blog/2008/sep/18/creating-django-superuser-automatically/ Sorry for littering your blog.

Reply

Kevin Gann on October 1, 2008
Thanks for this!

Reply

Reply