#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.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701828d0d0fd4-6b4a6f3f-f308-4dde-826b-683c71882d08-000000%40eu-central-1.amazonses.com.

Reply via email to