Can UUIDField be used as default_auto_field in Django 3.2.^?

Viewed 3289

I have been using UUIDField as my primary key in Django. My project has a hierarchy of models with inherited fields, and at the top, I have the following superclass:

import uuid
from django.db import models

class HasIDMixin(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True, name='id')

After updating to Django 3.2.4, I get the following warning:

WARNINGS:
app_base.MyProject: (models.W042) Auto-created primary key used when not defining a primary key type, by default 'django.db.models.AutoField'.
    HINT: Configure the DEFAULT_AUTO_FIELD setting or the AppBaseConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.

Following the advice of the warning, I tried both the DEFAULT_AUTO_FIELD in settings.py and the default_auto_field in the app_config and I get the following error:

ValueError: Primary key 'django.db.models.UUIDField' referred by DEFAULT_AUTO_FIELD must subclass AutoField.

I have seen others approach this problem with a custom child class to both UUIDField and AutoField (https://code.djangoproject.com/ticket/32577) but no working solution has been posted. Is this currently possible in Django 3.2.^? If not should I find a different primary key solution or roll back?

1 Answers

When one does not set a model field to be the primary key for that model Django will automatically add a field to your model named id which will be used as the primary key. This automatically added key is usually AutoField. From Django 3.2 onwards Django allows you to set what type of AutoField will be used for these automatically generated primary key fields by setting DEFAULT_AUTO_FIELD.

Considering you explicitly set a primary key for your model Django will not generate a field for it. But still you should specify DEFAULT_AUTO_FIELD as you might have some model where you don't specify the primary key. You can safely keep your UUIDField in your model as it is and also set DEFAULT_AUTO_FIELD like so:

DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' # Or one of the other options as per your choice
Related