#22758 closed Bug (invalid)
Makemigrations puts subclasses of abstract models in the wrong app
Reported by: | Craig de Stigter | Owned by: | Aymeric Augustin |
---|---|---|---|
Component: | Core (Other) | Version: | 1.7-beta-2 |
Severity: | Release blocker | Keywords: | app-loading |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
If I define a concrete model that inherits an abstract base from a different app, like so:
class AbstractModel(models.Model): a = models.CharField(max_length=100) class Meta: abstract = True app_label = 'otherapp' class MyModel(AbstractModel): b = models.CharField(max_length=255)
Then makemigrations tells me nothing has changed.
$ ./manage.py makemigrations foo No changes detected in app 'foo'
Because it's assigned my model to the app containing the abstract class:
$ ./manage.py makemigrations otherapp Migrations for 'otherapp': 0002_auto_20140603_2330.py: - Create model MyModel
There is a workaround: If I instead explicitly supply app_label
on my model it works as expected:
class MyModel(AbstractModel): b = models.CharField(max_length=255) class Meta: app_label = 'foo'
$ ./manage.py makemigrations foo Migrations for 'foo': 0001_initial.py: - Create model MyModel
Change History (7)
comment:1 by , 10 years ago
Component: | Migrations → Core (Other) |
---|
comment:2 by , 10 years ago
Also worth noting: This only occurs with an explicit app_label declaration. It's fine if the models just normally live in the separate apps' model files.
comment:3 by , 10 years ago
This only occurs with an explicit app_label declaration
That wasn't my experience. I encountered the issue with django-typed-models, where the abstract model was located in the typedmodels
app, and the concrete model was in some other app.
comment:4 by , 10 years ago
Keywords: | app-loading added |
---|---|
Owner: | changed from | to
Status: | new → assigned |
comment:6 by , 10 years ago
Resolution: | → invalid |
---|---|
Status: | assigned → closed |
You're seeing the documented behavior. If you set an app_label, it will be inherited by child classes, like all Meta attributes except abstract = True
: https://docs.djangoproject.com/en/dev/topics/db/models/#meta-inheritance.
Abstract models don't do anything with their app_label as they aren't added to the app registry. The only purpose of providing an app_label is to make it apply to inherited classes.
If Django didn't behave that way in previous versions, that was a bug, and it has been fixed.
Also, note the existence of the opposite ticket for proxy models: #11078.
comment:7 by , 10 years ago
Okay, I guess that makes sense. For context, I was doing this because I was getting this deprecation warning:
~/code/django-typed-models/typedmodels/models.py:60: RemovedInDjango19Warning: Model class typedmodels.models.TypedModel doesn't declare an explicit app_label and either isn't in an application in INSTALLED_APPS or else was imported before its application was loaded. Its app_label will be set to None in Django 1.9.
... but with a fresh coffee it seems I'm not getting it any more. Probably some error on my part. Thanks :)
This looks to be a problem in app loading - I've confirmed that on 1.6 it's fine, on 1.7 even get_models() puts it in the wrong app. Reassigning component, will come back around to fix after migrations if nobody else gets there.