#29177: Unmanaged models with ForeignKeys do not get those fields serialized 
into
their migration state when CreateModel happens.
----------------------------------------+------------------------
               Reporter:  Keryn Knight  |          Owner:  nobody
                   Type:  Bug           |         Status:  new
              Component:  Migrations    |        Version:  master
               Severity:  Normal        |       Keywords:
           Triage Stage:  Unreviewed    |      Has patch:  0
    Needs documentation:  0             |    Needs tests:  0
Patch needs improvement:  0             |  Easy pickings:  0
                  UI/UX:  0             |
----------------------------------------+------------------------
 Given models like the following, where `B` is unmanaged, and `C` is a
 normal concrete `Model`:

 {{{
 from django.db import models

 class A(models.Model):
     class Meta:
         db_table = "test_a"


 class B(models.Model):
     a = models.ForeignKey(A, related_name="+", on_delete=models.CASCADE)

     class Meta:
         managed = False
         db_table = "test_b"


 class C(models.Model):
     a = models.ForeignKey(A, related_name="+", on_delete=models.CASCADE)

     class Meta:
     db_table = "test_c"
 }}}

 when `python manage.py makemigrations <appname>` is called, `B` ends up
 looking like:
 {{{
 migrations.CreateModel(
     name='B',
     fields=[
         ('id', models.AutoField(auto_created=True, primary_key=True,
 serialize=False, verbose_name='ID')),
     ],
     options={
         'db_table': 'test_b',
         'managed': False,
     },
 )
 }}}
 whilst `C` correctly gets:
 {{{
 migrations.CreateModel(
     name='C',
     fields=[
         ('id', models.AutoField(auto_created=True, primary_key=True,
 serialize=False, verbose_name='ID')),
         ('a',
 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
 related_name='+', to='whee.A')),
     ],
     options={
         'db_table': 'test_c',
     },
 )
 }}}
 Because `B` doesn't have the `a` attribute, any subsequent data migrations
 which would like to query on it, like so:
 {{{
 def forwards(apps, schema_editor):
     B = apps.get_model('whee', 'B')
     B.objects.filter(a=1)
 }}}
 will crash.

 With the assistance of Markus on IRC:
 {{{
 MarkusH: do you want to try what's gonna happen when you just drop the if-
 condition in
 
https://github.com/django/django/blob/75527c0f8360ae3555fcf67ce19b4cb910b69b9d/django/db/migrations/autodetector.py#L570-L572
 ?
 }}}

 commenting out the lines
 {{{
 if not model_opts.managed:
     continue
 }}}

 allows the autodetector to generate the following:
 {{{
 migrations.CreateModel(
     name='A',
     fields=[
         ('id', models.AutoField(auto_created=True, primary_key=True,
 serialize=False, verbose_name='ID')),
     ],
     options={
         'db_table': 'test_a',
     },
 ),
 migrations.AddField(
     model_name='b',
     name='a',
     field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
 related_name='+', to='whee.A'),
 )
 }}}
 and subsequently the data migration can access `B.a`

 If `A` itself is `managed=False` the migration generated is instead:
 {{{
 migrations.CreateModel(
     name='B',
     fields=[
         ('id', models.AutoField(auto_created=True, primary_key=True,
 serialize=False, verbose_name='ID')),
         ('a',
 models.ForeignKey(on_delete=django.db.models.deletion.CASCADE,
 related_name='+', to='whee.A')),
     ],
     options={
         'db_table': 'test_b',
         'managed': False,
     },
 )
 }}}

 Running the test suite via `./runtests.py` as of commit
 75527c0f8360ae3555fcf67ce19b4cb910b69b9d doesn't seem to cause any
 failures, with those lines commented out.

 Markus also pointed out commit
 
https://github.com/django/django/commit/215aa4f53b6bbd07d5c1eecfa94e7fcd00da813e
 which references #23415

 I noticed this "issue" while bringing a project up from 1.9, so it's not a
 recent problem.

-- 
Ticket URL: <https://code.djangoproject.com/ticket/29177>
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 [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.d7cd9d1305e45901ff540d85eb1dfbc5%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to