Search code examples
djangodjango-authentication

Least painful way of not using int4 as primary key in Django user models?


I'm new to Django, and upon running the first migration, it seems the primary key ID of the auth_users table is an int4. Looking through the docs, it seems if I use any kind of custom User model, for example to bigint or uuid, I am opening a can of worms and losing Django Admin functionality and possibly all sorts of auth scaffolding functionality?

Is there a standard way of not using int4 that I'm failing to see, let's say using UUID, short of going full custom on the auth backend?

Tried custom model extending django.contrib.auth.models.AbstractUser. Django Admin stops working, which seems expected according to documentation. However, auth scaffolding, such as python manage.py createsuperuser also starts throwing errors, such as django.db.utils.IntegrityError: null value in column "id" of relation "users_user" violates not-null constraint. This is when id is a Postgres UUID.

Here's the User model:

class User(AbstractUser):
    id = models.UUIDField(primary_key=True)

Solution

  • To make my (implied) comment an answer:

    if you don't specify an AutoField() (i.e. "let the database decide") as your primary key, you'll need to specify some implicit primary key.

    class User(AbstractUser):
        id = models.UUIDField(primary_key=True, default=uuid.uuid4)
    

    is an obvious way to generate a random UUIDv4 for a new model, or if you like to have more control, e.g. via ULIDs, you could use ulid2:

    class User(AbstractUser):
        id = models.UUIDField(primary_key=True, default=ulid2.generate_ulid_as_uuid)