10

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?

Anne Haley
  • 160
  • 2
  • 10
  • The `DEFAULT_AUTO_FIELD` will only be used if you don't explicitly specify the primary key field on your model. Just set that setting to a suitable auto field of your choice and keep your `UUIDField` as it is currently in your model. – Abdul Aziz Barkat Jun 06 '21 at 16:41
  • @AbdulAzizBarkat this seems to have worked and made the warning go away. Is this a band-aid solution or will Django truly ignore that setting if all my models inherit from the HasIDMixin superclass? If this is a true solution, can you post this as an answer so I can mark it the solution? – Anne Haley Jun 06 '21 at 17:05
  • No it is not a bandaid solution, Django will only generate the pk field automatically for your model if it already doesn't have one. – Abdul Aziz Barkat Jun 06 '21 at 17:11
  • See this related Django feature request: https://code.djangoproject.com/ticket/32577 – phoenix Mar 14 '22 at 13:15

1 Answers1

6

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
Abdul Aziz Barkat
  • 19,475
  • 3
  • 20
  • 33
  • 1
    Thanks for this great Answer.i have 70 tables in my database and now i want to change the id(pk) to BigAutoField for all tables.can i use `DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'` ? and will the Django User model also change his pk ? – Thierno Amadou Sow Nov 22 '21 at 16:37
  • @amadousow you might have to do a bit more if you have any `ManyToManyField`s with an auto generated through table (In case you don't specify a through table Django creates one), see the note in the [documentation](https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field) for this. – Abdul Aziz Barkat Nov 22 '21 at 16:48