Skip to content
Advertisement

Django: Create a superuser in a data migration

Goal: automatically creating a superuser

I’m trying to create a default user, specifically a superuser, in an early data migration, so whenever my Django application is run in my Docker container, it already has a superuser with which I can access the admin site.

I had already tried different options for creating said superuser, and although I have some functioning ones (based on the command parameter of my docker-compose file), I’ve seen when adding initial data to a Django project, the best practice is to do it through a Data Migration.

My custom user

In my Django project I’ve extended the AbstactBaseUser so I can change the default username field requirement for the email field. My User is as such:

JavaScript

Failed attempts

By following the Django documentation here I tried making my superuser in a data migration with the following code, located in a file called 0002_data_superuser in the migrations folder of my app:

JavaScript

When running my docker-compose, however, I run into this error:

JavaScript

I’ve tried debugging by printing the Manager and, indeed, it does not have the create_superuser necessary for this. My next thought was to try to reproduce what create_superuser does myself, but I find it quite impossible given that a lot of methods for managing passwords, hashing, normalizing emails and stuff are not available to me.

I gather from all of this that the problem is that the Manager, for some reason, is not available during migrations, and I’d like to know if there’s a solution to this.

Advertisement

Answer

Reproducing create_user functionality manually

Checking out a bit more the source code of Django I found at there is a way to reproduce the functionality from create_superuser. By importing BaseUserManager and the classmethod make_password from django.contrib.auth.hashers, I came up with this:

JavaScript

which does the trick.

Still, I don’t like it much as a solution given that it requires reeimplementing an already existing Django method that just is not accessible at this point of the program.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement