I'm trying create a django app with multiple subapps. My current dir layout for the app is (filtered out admin.py, test.py and views.py for brevity):
myapp
__init__.py
models.py
subapp1/
__init__.py
models.py
subapp2
__init__.py
models.py
Where myapp/models.py looks like:
class Foo(models.Model):
name = models.CharField(max_length=32)
and myapp/subapp1/models.py looks like:
class Bar(models.Model):
foo = models.ForeignKey('myapp.Foo')
some_other_field = models.CharField(max_length=32)
and myapp/subapp2/models.py looks like:
class Baz(models.Model):
bar = models.ForeignKey('subapp1.Bar')
In my settings.py I have:
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
'myapp.subapp1',
'myapp.subapp2'
)
However when I attempt to run ./manage.py makemigrations myapp.subapp1
I get the error:
App 'myapp.subapp1' could not be found. Is it in INSTALLED_APPS?
But I am able to run ./manage.py makemigrations subapp1
and the equivalent for subapp2 successfully. What I'm worried about is app namespace collisions.
If I add a myapp/subapp1/apps.py
from django.apps import AppConfig
class SubApp1Config(AppConfig):
name = 'myapp.subapp1'
label = 'myapp.subapp1'
and then to myapp/subapp1/__init__.py
default_app_config = 'myapp.subapp1.apps.SubApp1Config'
Do the equivalent for 'myapp/subapp2' and comment out 'myapp.app2' from INSTALLED_APPS
I can then run ./manage.py makemigrations myapp.subapp1
successfully.
However if I then uncomment myapp.subapp2
from INSTALLED_APPS
and change myapp/subapp2/models.py to look like:
class Baz(models.Model):
bar = models.ForeignKey('myapp.subapp1.Bar')
and then run ./manage.py makemigrations myapp.subapp2
I get:
SystemCheckError: System check identified some issues:
ERRORS:
myapp.subapp2.Baz.bar: (fields.E300) Field defines a relation with model 'myapp.subapp1.Bar', which is either not installed, or is abstract.
How am I supposed to describe the foreign key relation between myapp.subapp2.Baz.bar
and myapp.subapp1.Bar
?
Thanks in advance.
I actually figured this out long ago, but I suppose I shouldn't keep a question unanswered. I didn't end up having to use this - it was merely an exercise in making part of an app optional. Having a foreign key between optional subapps was a bit contrived, I was simply trying to figure out how to reference them.
It turned out I was simply confused between the app_label
and what you put in INSTALLED_APPS
In this case, I'd simply set the app_labels to myapp_subapp1
and myapp_subapp2
, however, in INSTALLED_APPS, they'd be installed as myapp.subapp1
and myapp.subapp2
.
This will both list the subapps when you type ./manage.py showmigrations
as myapp_subapp1
and myapp_subapp2
rather than subapp1
and subapp2
, which was worrying as a subapp with a real name might clash with something else. For instance, I don't like how django-mutant
doesn't namespace it's contrib stuff, so you end up with app_labels like web
, text
, which could totally class with something instead of mutant_web
, etc.
Then when using foreign keys they'd be referenced as myapp_subapp1.Bar
instead of what I was doing previously as 'myapp.subapp1.Bar'