Skip to content

Python Django: How to Resolve Warning 'Auto-Created Primary Key Used When Not Defining a Primary Key Type"

How to fix Django 3.2+ warnings about auto-created primary keys by configuring DEFAULT_AUTO_FIELD, app-level defaults, or explicit model definitions for BigAutoField, AutoField, UUIDs, or custom keys.

If you've upgraded to Django 3.2 or later, you've likely encountered this warning:

WARNINGS:
myapp.MyModel: (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 AppConfig.default_auto_field
attribute to point to a subclass of AutoField, e.g. 'django.db.models.BigAutoField'.

This warning appears because Django changed its default primary key behavior starting in version 3.2. This guide explains why the warning occurs and walks you through three methods to fix it, so you can choose the approach that best fits your project.

Why Does This Warning Appear?

Every Django model needs a primary key: a unique identifier for each row in the database. If you don't define one explicitly, Django auto-creates one for you.

  • Before Django 3.2: The auto-created primary key was an AutoField (32-bit integer, max ~2.1 billion).
  • Django 3.2 and later: The default changed to BigAutoField (64-bit integer, max ~9.2 quintillion).

The warning tells you that Django is auto-creating a primary key and wants you to explicitly choose which type to use. This prevents silent, potentially breaking changes, especially when upgrading existing projects where the database already uses 32-bit integer keys.

Method 1: Set the Global Default in settings.py

The quickest way to silence the warning across your entire project is to set DEFAULT_AUTO_FIELD in your settings.py file.

settings.pypython
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

This uses a 64-bit integer, which supports a much larger range of IDs and is the modern Django default.

Option B: Use AutoField (For Backward Compatibility)

settings.pypython
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

Use this if you're upgrading an existing project and want to maintain compatibility with your current database schema without generating unnecessary migrations.

Method 2: Set the Default per App in apps.py

If different apps in your project need different primary key types, you can configure the default at the app level using AppConfig.default_auto_field:

myapp/apps.pypython
from django.apps import AppConfig

class MyappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'myapp'

This setting overrides the global DEFAULT_AUTO_FIELD for all models within that specific app.

Example: Mixed Configuration

legacy_app/apps.pypython
from django.apps import AppConfig

class LegacyAppConfig(AppConfig):
    default_auto_field = 'django.db.models.AutoField'  # Keep 32-bit for legacy tables
    name = 'legacy_app'
new_app/apps.pypython
from django.apps import AppConfig

class NewAppConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'  # Use 64-bit for new tables
    name = 'new_app'

Method 3: Explicitly Define a Primary Key in Each Model

For maximum control, you can define the primary key directly in each model. This overrides both the global and app-level defaults and makes the schema completely explicit.

Using BigAutoField

from django.db import models

class Product(models.Model):
    id = models.BigAutoField(primary_key=True)
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

Using AutoField

from django.db import models

class Category(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50)

Using UUIDField

UUID primary keys are useful for distributed systems, APIs, or when you don't want sequential, guessable IDs:

import uuid
from django.db import models

class Order(models.Model):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    customer_name = models.CharField(max_length=100)
    total = models.DecimalField(max_digits=10, decimal_places=2)

Using CharField with a Custom Generator

For human-readable or formatted primary keys:

import random
import string
from django.db import models

def generate_order_code():
    """Generate a code like 'ORD-A3bX9k'."""
    chars = string.ascii_letters + string.digits
    random_part = ''.join(random.choices(chars, k=6))
    return f"ORD-{random_part}"

class Order(models.Model):
    code = models.CharField(
        max_length=20,
        primary_key=True,
        default=generate_order_code,
        editable=False
    )
    description = models.TextField()

Which Method Should You Choose?

Approach Scope Best For
DEFAULT_AUTO_FIELD in settings.py Entire project New projects or full upgrades. Quickest single fix
default_auto_field in apps.py Single app Projects with mixed legacy and new apps
Explicit field in each model Single model Models needing UUID, CharField, or custom primary keys

Recommended strategy:

  1. Set DEFAULT_AUTO_FIELD in settings.py as your baseline.
  2. Override at the app level only if specific apps need different behavior.
  3. Define explicit primary keys on individual models only when you need a non-integer type (UUID, CharField, etc.).

Handling Migrations After the Fix

After configuring your primary key settings, you may need to generate and apply migrations:

python manage.py makemigrations
python manage.py migrate

Important Considerations

  • Setting DEFAULT_AUTO_FIELD to AutoField on an existing project that already uses AutoField will typically generate no new migrations. It just silences the warning.
  • Changing from AutoField to BigAutoField on existing models will generate migrations that alter the column type in the database. This can be time-consuming on large tables.
  • Changing from AutoField to UUIDField is a breaking change that requires careful data migration, as existing integer IDs cannot be directly converted to UUIDs.

Safe Approach for Existing Projects

If you're upgrading an existing project and simply want to stop the warning without changing your database, set:

settings.pypython
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'

This tells Django to continue using the same AutoField your existing database already uses, generating no migrations and requiring no schema changes.

Conclusion

The "Auto-created primary key" warning in Django 3.2+ is easy to resolve once you understand the three available approaches:

  • Set DEFAULT_AUTO_FIELD in settings.py for a project-wide fix: this is the simplest and most common solution.
  • Configure default_auto_field in apps.py when different apps need different primary key types.
  • Define primary keys explicitly in models when you need non-standard types like UUIDField or CharField.

For existing projects being upgraded, setting DEFAULT_AUTO_FIELD = 'django.db.models.AutoField' is the safest choice: it preserves your current schema and eliminates the warning without generating any migrations. For new projects, BigAutoField is the recommended default, providing ample room for growth.

Navigation