[Django] #33914: App level default_auto_field is ignored for m2m through tables

19 views
Skip to first unread message

Django

unread,
Aug 11, 2022, 9:17:03 AM8/11/22
to django-...@googlegroups.com
#33914: App level default_auto_field is ignored for m2m through tables
-------------------------------------+-------------------------------------
Reporter: Borislav | Owner: nobody
Ivanov |
Type: | Status: new
Uncategorized |
Component: | Version: 3.2
Migrations |
Severity: Normal | Keywords: default_auto_field
Triage Stage: | Has patch: 0
Unreviewed |
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------+-------------------------------------
When default_auto_field is defined on app level, it is ignored for
m2m through tables. This effectively defaults them to what is defined
in DEFAULT_AUTO_FIELD setting.

This happens in two different code paths, ultimately affecting
Options::_get_default_pk_class:

1. When AppConfigStub is supplied instead of AppConfig it is stripped from
most of the properties including default_auto_field.
2. When the first migration for a given app is applied, we don't get any
app config as it is lazily registered in StateApps::register_models. As
this is the first model for this app, the config is no there yet.

Here's modified configuration for polls app that demonstrates the issue:

mysite/settings.py:
{{{#!python
...
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'empty',
}
}
...
DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
}}}

mysite/polls/apps.py:
{{{#!python
...
class PollsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'polls'
}}}

mysite/polls/models.py:
{{{#!python
...
class KlassA(models.Model):
field_a = models.CharField(max_length=200)


class KlassB(models.Model):
field_b = models.CharField(max_length=200)
m2m_to_a = models.ManyToManyField(
KlassA, blank=True
)

}}}

Then run `makemigrations` and `sqlmigrate polls 0001_initial`:
{{{
BEGIN;
--
-- Create model KlassA
--
CREATE TABLE "polls_klassa" ("id" bigserial NOT NULL PRIMARY KEY,
"field_a" varchar(200) NOT NULL);
--
-- Create model KlassB
--
CREATE TABLE "polls_klassb" ("id" bigserial NOT NULL PRIMARY KEY,
"field_b" varchar(200) NOT NULL);
CREATE TABLE "polls_klassb_m2m_to_a" ("id" serial NOT NULL PRIMARY KEY,
"klassb_id" bigint NOT NULL, "klassa_id" bigint NOT NULL);
ALTER TABLE "polls_klassb_m2m_to_a" ADD CONSTRAINT
"polls_klassb_m2m_to_a_klassb_id_klassa_id_05b47d06_uniq" UNIQUE
("klassb_id", "klassa_id");
ALTER TABLE "polls_klassb_m2m_to_a" ADD CONSTRAINT
"polls_klassb_m2m_to_a_klassb_id_58ef37e1_fk_polls_klassb_id" FOREIGN KEY
("klassb_id") REFERENCES "polls_klassb" ("id") DEFERRABLE INITIALLY
DEFERRED;
ALTER TABLE "polls_klassb_m2m_to_a" ADD CONSTRAINT
"polls_klassb_m2m_to_a_klassa_id_b63f26b4_fk_polls_klassa_id" FOREIGN KEY
("klassa_id") REFERENCES "polls_klassa" ("id") DEFERRABLE INITIALLY
DEFERRED;
CREATE INDEX "polls_klassb_m2m_to_a_klassb_id_58ef37e1" ON
"polls_klassb_m2m_to_a" ("klassb_id");
CREATE INDEX "polls_klassb_m2m_to_a_klassa_id_b63f26b4" ON
"polls_klassb_m2m_to_a" ("klassa_id");
COMMIT;
}}}

Here we get `CREATE TABLE "polls_klassb_m2m_to_a" ("id" serial NOT NULL
PRIMARY KEY...`

If we change in settings.py `DEFAULT_AUTO_FIELD` to
`django.db.models.BigAutoField` we get `CREATE TABLE
"polls_klassb_m2m_to_a" ("id" bigserial NOT NULL PRIMARY KEY...`

I did a little bit of research and found out 2 probable causes affecting
Options::_get_default_pk_class:

1. When AppConfigStub is supplied instead of AppConfig it is stripped
from most of the properties including default_auto_field.
2. When the first migration for a given app is applied, we don't get
any app config as it is lazily registered in StateApps::register_models.
As this is the first model for this app, the config is no there yet.

--
Ticket URL: <https://code.djangoproject.com/ticket/33914>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Aug 11, 2022, 9:23:31 AM8/11/22
to django-...@googlegroups.com
#33914: App level default_auto_field is ignored for m2m through tables
-------------------------------------+-------------------------------------
Reporter: Borislav Ivanov | Owner: nobody
Type: Uncategorized | Status: closed
Component: Database layer | Version: 3.2
(models, ORM) |
Severity: Normal | Resolution: duplicate
Keywords: default_auto_field | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0

Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Mariusz Felisiak):

* status: new => closed
* resolution: => duplicate
* component: Migrations => Database layer (models, ORM)


Comment:

Duplicate of #32674, see also a note in
[https://docs.djangoproject.com/en/stable/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD docs].

--
Ticket URL: <https://code.djangoproject.com/ticket/33914#comment:1>

Django

unread,
Aug 12, 2022, 4:07:22 AM8/12/22
to django-...@googlegroups.com
#33914: App level default_auto_field is ignored for m2m through tables
-------------------------------------+-------------------------------------
Reporter: Borislav Ivanov | Owner: nobody
Type: Uncategorized | Status: closed
Component: Database layer | Version: 3.2
(models, ORM) |
Severity: Normal | Resolution: duplicate
Keywords: default_auto_field | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Borislav Ivanov):

Replying to [comment:1 Mariusz Felisiak]:


> Duplicate of #32674, see also a note in
[https://docs.djangoproject.com/en/stable/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD docs].

I see your point here, however this is not exactly the same case.

#32674 refers to change in DEFAULT_AUTO_FIELD not being reflected in a
migration. This report refers to app level default_auto_field not taking
precedence over DEFAULT_AUTO_FIELD as stated in
https://docs.djangoproject.com/en/4.1/ref/models/fields/#primary-key.

Having said this I do understand this being postponed as feature request,
just wanted to be sure that the use case is clear enough.

--
Ticket URL: <https://code.djangoproject.com/ticket/33914#comment:2>

Django

unread,
Aug 12, 2022, 4:35:59 AM8/12/22
to django-...@googlegroups.com
#33914: App level default_auto_field is ignored for m2m through tables
-------------------------------------+-------------------------------------
Reporter: Borislav Ivanov | Owner: nobody
Type: Uncategorized | Status: closed
Component: Database layer | Version: 3.2
(models, ORM) |
Severity: Normal | Resolution: duplicate
Keywords: default_auto_field | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by Mariusz Felisiak):

Replying to [comment:2 Borislav Ivanov]:


> Replying to [comment:1 Mariusz Felisiak]:
> > Duplicate of #32674, see also a note in
[https://docs.djangoproject.com/en/stable/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD docs].
>
> I see your point here, however this is not exactly the same case.
>
> #32674 refers to change in DEFAULT_AUTO_FIELD not being reflected in a
migration. This report refers to app level default_auto_field not taking
precedence over DEFAULT_AUTO_FIELD as stated in
https://docs.djangoproject.com/en/4.1/ref/models/fields/#primary-key.
>
> Having said this I do understand this being postponed as feature
request, just wanted to be sure that the use case is clear enough.

As far as I'm aware fixing #32674 should also fix a precedence.

--
Ticket URL: <https://code.djangoproject.com/ticket/33914#comment:3>

Reply all
Reply to author
Forward
0 new messages