'Migrating models of dependencies when changing DEFAULT_AUTO_FIELD

I'm using Django 3.2. I've changed added this line to settings.py:

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

I then ran these commands:

$ python manage.py makemigrations
$ python manage.py migrate

The makemigrations command creates new migration files for my apps, not just the apps that I have created, but also in my dependencies. For example, I'm using django-allauth, and this file was created in my virtual environment (virtualenv):

 .venv/lib/python3.8/site-packages/allauth/account/migrations/0003_auto_20210408_1526.py

This file is not shipped with django-allauth. When I deploy this application from git, this file is not included.

What should I do instead? How can I switch DEFAULT_AUTO_FIELD without the need to create new migration files for dependencies like django-allauth?



Solution 1:[1]

I work on a big project, we upgraded Django from 2.2. to 3.2 and then have got a need to create all new models with Big Integer (Int8) (PostgreSQL) field instead of default Integer (Int4).

When I defined it in settings.py:

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

I got the same problem, but with own apps - Django tried to make me to migrate 135 models I had, but I didn't want to do it. I only wanted to create new models with BigInt and manipuate olds manually.

I found the next solution. I changed the field to custom:

DEFAULT_AUTO_FIELD = 'project.db.models.CustomBigAutoField'

And then overrided its deconstruction:

from django.db import models

class CustomBigAutoField(models.BigAutoField):
    """Int8 field that is applied only for new models."""

    def deconstruct(self):
        name, path, args, kwargs = super().deconstruct()
        if getattr(self, 'model', None):
            path = 'django.db.models.AutoField'
        return name, path, args, kwargs

As I discovered, fields of new models don't have a back reference to their models, so path wouldn't be overridden for them. We override path because Django checks whether a model is changed by a key, that includes the path to this field. So we deceive Django and it thinks that existing model didn't changed.

I might not see the whole picture, but I tested it with different existing and new models and it worked for me. If someone tells me why this solution is bad, I'd be grateful.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Praetorian