﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22735	"1.7b4 - Wrong migration dependency calculation when models.ForeignKey ""to"" field specified as string"	make.kernel@…	nobody	"I have project with two applications - customer and vaucher, here is a vaucher.Vaucher model code i have
{{{
class Vaucher(models.Model):
    issuer = models.ForeignKey(User, related_name='vauchers')
    amount = models.DecimalField(max_digits=6, decimal_places=2, default=0)
    created = models.DateTimeField(auto_now=True, auto_now_add=True)
    applied = models.DateTimeField(auto_now=True, auto_now_add=True)
    agreement = models.ForeignKey('customer.Agreement', related_name='vauchers')
}}}
it produces following migration
{{{
class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('customer', '__first__'),
    ]

    operations = [
        migrations.CreateModel(
            name='Vaucher',
            fields=[
                ('id', models.AutoField(auto_created=True, verbose_name='ID', primary_key=True, serialize=False)),
                ('issuer', models.ForeignKey(to=settings.AUTH_USER_MODEL, to_field='id')),
                ('amount', models.DecimalField(default=0, max_digits=6, decimal_places=2)),
                ('created', models.DateTimeField(auto_now=True, auto_now_add=True)),
                ('applied', models.DateTimeField(auto_now=True, auto_now_add=True)),
                ('agreement', models.ForeignKey(to='customer.Agreement', to_field='id')),
            ],
            options={
            },
            bases=(models.Model,),
        ),
    ]
}}}
With this migration  ./manage.py migrate gives me following error:
{{{
  Applying vaucher.0001_initial...Traceback (most recent call last):
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/apps/config.py"", line 152, in get_model
    return self.models[model_name.lower()]
KeyError: 'agreement'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/db/migrations/state.py"", line 76, in render
    model = self.apps.get_model(lookup_model[0], lookup_model[1])
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/apps/registry.py"", line 190, in get_model
    return self.get_app_config(app_label).get_model(model_name.lower())
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/apps/config.py"", line 155, in get_model
    ""App '%s' doesn't have a '%s' model."" % (self.label, model_name))
LookupError: App 'customer' doesn't have a 'agreement' model.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ""./manage.py"", line 10, in <module>
    execute_from_command_line(sys.argv)
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/core/management/__init__.py"", line 427, in execute_from_command_line
    utility.execute()
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/core/management/__init__.py"", line 419, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/core/management/base.py"", line 288, in run_from_argv
    self.execute(*args, **options.__dict__)
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/core/management/base.py"", line 337, in execute
    output = self.handle(*args, **options)
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/core/management/commands/migrate.py"", line 146, in handle
    executor.migrate(targets, plan, fake=options.get(""fake"", False))
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/db/migrations/executor.py"", line 62, in migrate
    self.apply_migration(migration, fake=fake)
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/db/migrations/executor.py"", line 90, in apply_migration
    if self.detect_soft_applied(migration):
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/db/migrations/executor.py"", line 134, in detect_soft_applied
    apps = project_state.render()
  File ""/home/yuriy/dev/python/tools/django-stable-1.7.x/django/db/migrations/state.py"", line 86, in render
    model=lookup_model,
ValueError: Lookup failed for model referenced by field vaucher.Vaucher.agreement: customer.Agreement
}}}
because automatically created dependency {{{('customer', '__first__')}}} is wrong, it should be {{{('customer', '0002_agreement')}}} where Agreement model actually created. 

When I change migration file manually it works fine.
When I remove quotes and put required import into models.py {{{agreement = models.ForeignKey(customer.Agreement, related_name='vauchers')}}} makemigrations generates correct dependency and it works fine.

----

Note - I'm using path from #22659 because of initial data loading fix provided at https://github.com/django/django/pull/2703

"	Bug	closed	Migrations		Normal	fixed			Unreviewed	0	0	0	0	0	0
