When you define a model in Django without specifying a primary key, Django will automatically create a primary key for you. The primary key is set to be an integer. If you want to override the field type, you can do so on a per model basis.
Starting in Django 3.2, you can now customise the type of the automatically created primary key in your settings.
Starting new projects in Django 3.2, the default type for primary keys is set to a
BigAutoField which is a 64 bit integer. However, earlier versions set the type of implicit primary keys to be integers.
This means that when you upgrade to 3.2, you will start to see warnings about the fact that you do not have an explicitly defined primary key type. Satisfying Django's requirements for an explicitly set primary key type is easy enough, but you also need to choose whether or not you want to upgrade your primary key field types from integer to 64 bit integer.
Having upgraded to 3.2, the suggestion in the official docs is to run
python -Wa manage.py test
You should see the warning and the hint to configure a DEFAULT_AUTO_FIELD
WARNINGS: blog.BlogPost: (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 BlogConfig.default_auto_field attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.
There are a few ways to fix this. Broadly speaking they fall into two categories - those that do not require a migration and those that do.
If you want the simplest upgrade path without migrations, you'll need to tell Django to set the DEFAULT_AUTO_FIELD to
AutoField which is, under the hood, an
IntegerField. There are a few places you can do this
Open your project's
settings.py and add a new line at the bottom of the file
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
If you prefer to set your field type on a per app basis rather than for the whole project, you can specify this in
apps.py. You might want to do this if you want a different auto field type per app. For a hypothetical project with a blog app, adding the
default_auto_field line in
apps.py will work:
from django.apps import AppConfig class BlogConfig(AppConfig): default_auto_field = 'django.db.models.AutoField' name = 'blog'
If you don't mind creating and running migrations, then you can embrace the new
BigAutoField. Again, there are a few ways to achieve this:
Open your project's
settings.py and add the following to the bottom:
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
You'll then need to create and run a migration to update your database to use the new field type. The migrations will alter the id field on your models. To create and run migration in a hypothetical application named
blog, you'd run the following commands
> python manage.py makemigrations blog > python manage.py sqlmigrate blog <migration_number>
As above, you can configure the setting on a per app basis, so in
apps.py, you can set the
from django.apps import AppConfig class BlogConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'my_app'
and again create and run migrations for your app.
If you prefer even more fine grained control, you can set a per model id field. A blogging app might have a
BlogPost model. You can explicitly set an id field on each model.
In a hypothetical blog application you would modify
class BlogPost(models.Model): id = models.BigAutoField(primary_key=True) # ...other fields
If you prefer, you can instead subclass a common base model. Perhaps it saves you some typing if you have a large number of models. In a hypothetical blog application, you would define a common base model and then inherit from it in each model
from django.db import models class CommonBaseModel(models.Model): id = models.BigAutoField(primary_key=True) class Meta: abstract = True # Create your models here. class BlogPost(CommonBaseModel): # ...other fields
In either of the two previous examples, you can use
AutoField instead of
BigAutoField if you prefer to keep your primary key as an integer. You still need to make and run migrations to be fully up to date though, because you've changed your model definitions.
Django 3.2 allows developers to customise the field type used when creating automatic primary keys. Upgrading means you'll Django will warn you that you do not have the field type set. To silence the warnings, you need to set the default auto field at a project, app, or model level.