[Django] #25145: Models of apps w/o migrations don't have relational fields to other apps w/o migrations when applying migrations

5 views
Skip to first unread message

Django

unread,
Jul 19, 2015, 9:35:36 PM7/19/15
to django-...@googlegroups.com
#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.

Django

unread,
Jul 19, 2015, 10:08:10 PM7/19/15
to django-...@googlegroups.com
#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 | Resolution:

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------------------------

Comment (by timgraham):

Don't you need to add a dependency to `wo_migrations1` on `w_migrations`
if you want to use its models? In which case, you have the case of
migrated apps depending on unmigrated apps which isn't supported.

https://docs.djangoproject.com/en/1.8/topics/migrations/#accessing-models-
from-other-apps

See also #24853 and the docs added in that ticket.

--
Ticket URL: <https://code.djangoproject.com/ticket/25145#comment:1>

Django

unread,
Jul 29, 2015, 3:27:21 PM7/29/15
to django-...@googlegroups.com
#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: closed
Component: Migrations | Version: 1.8
Severity: Normal | Resolution: duplicate

Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
----------------------------+--------------------------------------
Changes (by timgraham):

* status: new => closed
* resolution: => duplicate


--
Ticket URL: <https://code.djangoproject.com/ticket/25145#comment:2>

Reply all
Reply to author
Forward
0 new messages