#25145: Models of apps w/o migrations don't have relational fields to other apps
w/o migrations when applying migrations
--------------------------------------+------------------------
Reporter: MarkusH | Owner: nobody
Type: Bug | Status: new
Component: Migrations | Version: 1.8
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 |
--------------------------------------+------------------------
Consider the three apps `w_migrations`, `wo_migrations1` and
`wo_migrations2` with the following models:
`w_migrations`:
{{{#!python
class With(models.Model):
without1 = models.ForeignKey('wo_migrations1.Without1')
}}}
`wo_migrations1`:
{{{#!python
class Without1(models.Model):
without2 = models.ForeignKey('wo_migrations2.Without2')
}}}
`wo_migrations2`:
{{{#!python
class Without2(models.Model):
i = models.IntegerField()
}}}
When you create the migration for `w_migrations` and add an additional
`RunPython` operation:
{{{#!python
def forward(apps, schema_editor):
print(apps.get_model('wo_migrations1',
'Without1')._meta._get_fields())
operations = [
...,
migrations.RunPython(forward, migrations.RunPython.noop),
]
}}}
you will get the following output:
{{{#!python
(<django.db.models.fields.AutoField: id>,)
}}}
However, one would expect to see the `ForeignKey` to `wo_migrations2`,
too.
A fix should be rather simple by updating
`django.db.migrations.state.ModelState.from_model()` similar to those
lines:
{{{#!diff
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py
index b1cba07..4dd25ba 100644
--- a/django/db/migrations/state.py
+++ b/django/db/migrations/state.py
@@ -219,7 +219,7 @@ class StateApps(Apps):
for app_label in real_apps:
app = global_apps.get_app_config(app_label)
for model in app.get_models():
- self.real_models.append(ModelState.from_model(model,
exclude_rels=True))
+ self.real_models.append(ModelState.from_model(model,
exclude_rels=True, allow_rels_to=real_apps))
# Populate the app registry with a stub for each application.
app_labels = {model_state.app_label for model_state in
models.values()}
app_configs = [AppConfigStub(label) for label in sorted(real_apps
+ list(app_labels))]
@@ -346,14 +346,15 @@ class ModelState(object):
return self.name.lower()
@classmethod
- def from_model(cls, model, exclude_rels=False):
+ def from_model(cls, model, exclude_rels=False, allow_rels_to=[]):
"""
Feed me a model, get a ModelState representing it out.
"""
# Deconstruct the fields
fields = []
for field in model._meta.local_fields:
- if getattr(field, "remote_field", None) and exclude_rels:
+ if (exclude_rels and field.is_relation and
+ _get_app_label_and_model_name(field.related_model)[0]
not in allow_rels_to):
continue
if isinstance(field, OrderWrt):
continue
@@ -367,18 +368,20 @@ class ModelState(object):
model._meta.label,
e,
))
- if not exclude_rels:
- for field in model._meta.local_many_to_many:
- name, path, args, kwargs = field.deconstruct()
- field_class = import_string(path)
- try:
- fields.append((name, field_class(*args, **kwargs)))
- except TypeError as e:
- raise TypeError("Couldn't reconstruct m2m field %s on
%s: %s" % (
- name,
- model._meta.object_name,
- e,
- ))
+ for field in model._meta.local_many_to_many:
+ if (exclude_rels and field.is_relation and
+ _get_app_label_and_model_name(field.related_model)[0]
not in allow_rels_to):
+ continue
+ name, path, args, kwargs = field.deconstruct()
+ field_class = import_string(path)
+ try:
+ fields.append((name, field_class(*args, **kwargs)))
+ except TypeError as e:
+ raise TypeError("Couldn't reconstruct m2m field %s on %s:
%s" % (
+ name,
+ model._meta.object_name,
+ e,
+ ))
# Extract the options
options = {}
for name in DEFAULT_NAMES:
}}}
I believe this bug is also present on 1.8, haven't investigated though. If
it is, it is I think it is a regression from 1.7 to 1.8.
--
Ticket URL: <https://code.djangoproject.com/ticket/25145>
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/050.4a46f79087def1532c3954e516d3e626%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.