Opened 9 years ago
Closed 9 years ago
#25145 closed Bug (duplicate)
Models of apps w/o migrations don't have relational fields to other apps w/o migrations when applying migrations
Reported by: | Markus Holtermann | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.8 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Consider the three apps w_migrations
, wo_migrations1
and wo_migrations2
with the following models:
w_migrations
:
class With(models.Model): without1 = models.ForeignKey('wo_migrations1.Without1')
wo_migrations1
:
class Without1(models.Model): without2 = models.ForeignKey('wo_migrations2.Without2')
wo_migrations2
:
class Without2(models.Model): i = models.IntegerField()
When you create the migration for w_migrations
and add an additional RunPython
operation:
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:
(<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:
-
django/db/migrations/state.py
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index b1cba07..4dd25ba 100644
a b class StateApps(Apps): 219 219 for app_label in real_apps: 220 220 app = global_apps.get_app_config(app_label) 221 221 for model in app.get_models(): 222 self.real_models.append(ModelState.from_model(model, exclude_rels=True ))222 self.real_models.append(ModelState.from_model(model, exclude_rels=True, allow_rels_to=real_apps)) 223 223 # Populate the app registry with a stub for each application. 224 224 app_labels = {model_state.app_label for model_state in models.values()} 225 225 app_configs = [AppConfigStub(label) for label in sorted(real_apps + list(app_labels))] … … class ModelState(object): 346 346 return self.name.lower() 347 347 348 348 @classmethod 349 def from_model(cls, model, exclude_rels=False ):349 def from_model(cls, model, exclude_rels=False, allow_rels_to=[]): 350 350 """ 351 351 Feed me a model, get a ModelState representing it out. 352 352 """ 353 353 # Deconstruct the fields 354 354 fields = [] 355 355 for field in model._meta.local_fields: 356 if getattr(field, "remote_field", None) and exclude_rels: 356 if (exclude_rels and field.is_relation and 357 _get_app_label_and_model_name(field.related_model)[0] not in allow_rels_to): 357 358 continue 358 359 if isinstance(field, OrderWrt): 359 360 continue … … class ModelState(object): 367 368 model._meta.label, 368 369 e, 369 370 )) 370 if not exclude_rels: 371 for field in model._meta.local_many_to_many: 372 name, path, args, kwargs = field.deconstruct() 373 field_class = import_string(path) 374 try: 375 fields.append((name, field_class(*args, **kwargs))) 376 except TypeError as e: 377 raise TypeError("Couldn't reconstruct m2m field %s on %s: %s" % ( 378 name, 379 model._meta.object_name, 380 e, 381 )) 371 for field in model._meta.local_many_to_many: 372 if (exclude_rels and field.is_relation and 373 _get_app_label_and_model_name(field.related_model)[0] not in allow_rels_to): 374 continue 375 name, path, args, kwargs = field.deconstruct() 376 field_class = import_string(path) 377 try: 378 fields.append((name, field_class(*args, **kwargs))) 379 except TypeError as e: 380 raise TypeError("Couldn't reconstruct m2m field %s on %s: %s" % ( 381 name, 382 model._meta.object_name, 383 e, 384 )) 382 385 # Extract the options 383 386 options = {} 384 387 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.
Change History (2)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Don't you need to add a dependency to
wo_migrations1
onw_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.