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_labeland what you put inINSTALLED_APPSIn this case, I'd simply set the app_labels to
myapp_subapp1andmyapp_subapp2, however, in INSTALLED_APPS, they'd be installed asmyapp.subapp1andmyapp.subapp2.This will both list the subapps when you type
./manage.py showmigrationsasmyapp_subapp1andmyapp_subapp2rather thansubapp1andsubapp2, which was worrying as a subapp with a real name might clash with something else. For instance, I don't like howdjango-mutantdoesn't namespace it's contrib stuff, so you end up with app_labels likeweb,text, which could totally class with something instead ofmutant_web, etc.Then when using foreign keys they'd be referenced as
myapp_subapp1.Barinstead of what I was doing previously as 'myapp.subapp1.Bar'