Opened 4 years ago

Last modified 3 months ago

#32577 assigned New feature

Don't enforce `DEFAULT_AUTO_FIELD` to subclass from `AutoField` — at Initial Version

Reported by: Tomasz Wójcik Owned by: nobody
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: uuid
Cc: Diego Lima, Brian Helba, raydeal, johnthagen, Michael Kuron, Alireza Safari, Petr Přikryl, Wilson E. Husin, Luiz Braga, Dmytro Litvinov, Olivier Dalang, Ülgen Sarıkavak Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Default auto field introduced in #31007, as seen in the docs, is BigAutoField.

class BigAutoField(AutoFieldMixin, BigIntegerField):
    def get_internal_type(self):
        return 'BigAutoField'

    def rel_db_type(self, connection):
        return BigIntegerField().db_type(connection=connection)

Many projects prefer UUID field over big int for pk. So far we had to use a mixin for that but I am under the impression DEFAULT_AUTO_FIELD exists to lift this burden.

I'd expect something like this to work (additional adjustments might be needed)

from django.db import models
from django.db.models.fields import AutoFieldMixin


class UUIDAutoField(AutoFieldMixin, models.UUIDField):
    def get_internal_type(self):
        return 'UUIDAutoField'

    def rel_db_type(self, connection):
        return models.UUIDField().db_type(connection=connection)

But if I use this for DEFAULT_AUTO_FIELD I get the error

ValueError: Primary key 'common.fields.UUIDAutoField' referred by DEFAULT_AUTO_FIELD must subclass AutoField.

I noticed two things I want to share.

First, the default auto field BigAutoField is not subclassing AutoField so it's not consistent with the error message.

Second, AutoField is subclassing IntegerField. If I understand this correctly, users are limited to subclass IntegerField for DEFAULT_AUTO_FIELD. If so, there's no way to implement UUIDAutoField as DEFAULT_AUTO_FIELD.

I understand auto fields need to share a common interface but having to subclass IntegerField is a big constraint.

I'm happy to open a PR once I know what's the desired functionality. Possible solutions I see:

  • enforce subclassing from AutoFieldMixin instead of AutoField
  • I don't think this field has to be very generic because DB pk types are very limited. As far as I know, only ints and UUIDs make sense for pk. Maybe adding UUIDAutoField to django fields would make sense. That way it'd have to enforce subclass of AutoField or UUIDAutoField

Mentioned also in here, here and here.

Django==3.2rc1

Change History (0)

Note: See TracTickets for help on using tickets.
Back to Top