Overview

Django 3.2, released on April 6, 2021, is an LTS (Long Term Support) release. Its most impactful change is the DEFAULT_AUTO_FIELD setting, which lets you configure the auto-generated primary key type for new models. By default, Django used AutoField (32-bit integer); it is now recommended to use BigAutoField (64-bit integer). This release also introduces functional indexes and pymemcache support.

Key Features

DEFAULT_AUTO_FIELD

The DEFAULT_AUTO_FIELD setting controls the default primary key type used when a model does not explicitly define a primary key field. This change avoids overflow issues on high-volume tables.

python
# settings.py
# Recommended new default for new projects
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

# For existing projects, configure per application
# in apps.py
from django.apps import AppConfig

class CatalogConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'catalog'

# Or directly in the model
from django.db import models

class Transaction(models.Model):
    # Explicit BigAutoField for high-volume tables
    id = models.BigAutoField(primary_key=True)
    amount = models.DecimalField(max_digits=10, decimal_places=2)
    date = models.DateTimeField(auto_now_add=True)

    # BigAutoField supports up to 9,223,372,036,854,775,807
    # versus 2,147,483,647 for AutoField

Functional indexes

The Meta.indexes option now accepts expressions as arguments, allowing indexes on computed columns or database functions. This is especially useful for optimizing queries that filter on data transformations.

python
from django.db import models
from django.db.models import Index
from django.db.models.functions import Lower, ExtractYear

class Article(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=100)
    pub_date = models.DateField()
    is_published = models.BooleanField(default=False)

    class Meta:
        indexes = [
            # Index on lowercased title
            # Optimizes: Article.objects.filter(title__iexact='...')
            Index(
                Lower('title'),
                name='article_title_lower_idx',
            ),
            # Index on publication year
            # Optimizes: Article.objects.filter(
            #     pub_date__year=2024
            # )
            Index(
                ExtractYear('pub_date'),
                name='article_pub_year_idx',
            ),
            # Conditional (partial) index
            Index(
                'pub_date',
                name='article_published_date_idx',
                condition=models.Q(is_published=True),
            ),
        ]

pymemcache support

Django 3.2 adds a cache backend based on pymemcache, a more modern and actively maintained Memcached library, replacing the aging python-memcached.

python
# settings.py
CACHES = {
    'default': {
        # New pymemcache backend
        'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
        'LOCATION': '127.0.0.1:11211',
        'OPTIONS': {
            'no_delay': True,
            'connect_timeout': 2,
            'timeout': 5,
        },
    }
}

# Using the cache in a view
from django.core.cache import cache

def statistics(request):
    stats = cache.get('global_stats')
    if stats is None:
        stats = compute_statistics()  # expensive operation
        cache.set('global_stats', stats, timeout=300)
    return render(request, 'statistics.html', {'stats': stats})

Sources