#33914 closed Uncategorized (duplicate)
App level default_auto_field is ignored for m2m through tables
Reported by: | Borislav Ivanov | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 3.2 |
Severity: | Normal | Keywords: | default_auto_field |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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:
- When AppConfigStub is supplied instead of AppConfig it is stripped from most of the properties including default_auto_field.
- 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:
... DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'empty', } } ... DEFAULT_AUTO_FIELD = 'django.db.models.AutoField'
mysite/polls/apps.py:
... class PollsConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'polls'
mysite/polls/models.py:
... 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:
- When AppConfigStub is supplied instead of AppConfig it is stripped
from most of the properties including default_auto_field.
- 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.
Change History (3)
follow-up: 2 comment:1 by , 2 years ago
Component: | Migrations → Database layer (models, ORM) |
---|---|
Resolution: | → duplicate |
Status: | new → closed |
follow-up: 3 comment:2 by , 2 years ago
Replying to Mariusz Felisiak:
Duplicate of #32674, see also a note in 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.
comment:3 by , 2 years ago
Replying to Borislav Ivanov:
Replying to Mariusz Felisiak:
Duplicate of #32674, see also a note in 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.
Duplicate of #32674, see also a note in DEFAULT_AUTO_FIELD docs.