我正在尝试创建一个包含多个子应用程序的django应用程序。我目前的应用程序目录布局是(为了简洁起见,已过滤掉admin.py、test.py和views.py):
myapp
__init__.py
models.py
subapp1/
__init__.py
models.py
subapp2
__init__.py
models.py
myapp/models.py看起来像:
class Foo(models.Model):
name = models.CharField(max_length=32)
和myapp/subapp1/models.py看起来像:
class Bar(models.Model):
foo = models.ForeignKey('myapp.Foo')
some_other_field = models.CharField(max_length=32)
和myapp/subapp2/模型。py看起来像:
class Baz(models.Model):
bar = models.ForeignKey('subapp1.Bar')
在我的设置.py中,我有:
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'
)
然而,当我尝试运行./manage.py makemigrations myapp.subapp1
时,我得到了错误:
App 'myapp.subapp1' could not be found. Is it in INSTALLED_APPS?
但我能够成功地运行./manage.py makemigrations subapp1
和子应用程序2的等效程序。我担心的是应用程序命名空间冲突。
如果我添加myapp/subapp1/apps.py
from django.apps import AppConfig
class SubApp1Config(AppConfig):
name = 'myapp.subapp1'
label = 'myapp.subapp1'
然后到myapp/subapp1/__init__.py
default_app_config = 'myapp.subapp1.apps.SubApp1Config'
对"myapp/subapp2"执行等效操作,并从INSTALLED_APPS
中注释掉"myapp.app2"
然后我可以成功地运行./manage.py makemigrations myapp.subapp1
。
但是,如果我随后从INSTALLED_APPS 中取消注释myapp.subapp2
并更改myapp/subapp2/型号.py,使其看起来像:
class Baz(models.Model):
bar = models.ForeignKey('myapp.subapp1.Bar')
然后运行./manage.py makemigrations myapp.subapp2
我得到:
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.
我应该如何描述myapp.subapp2.Baz.bar
和myapp.subapp1.Bar
之间的外键关系?
提前谢谢。
我其实早就知道了,但我想我不应该让一个问题没有答案。我最终没有使用这个——这只是一个让应用程序的一部分成为可选的练习。在可选的子应用程序之间使用外键有点做作,我只是想弄清楚如何引用它们。
事实证明,我只是对app_label
和你在INSTALLED_APPS
中输入的内容感到困惑
在这种情况下,我只需将app_labels设置为myapp_subapp1
和myapp_subapp2
,但在INSTALLED_APPS中,它们将被安装为myapp.subapp1
和myapp.subapp2
。
当您将./manage.py showmigrations
键入为myapp_subapp1
和myapp_subapp2
而不是subapp1
和subapp2
时,这两者都会列出子应用程序,这令人担忧,因为具有真实名称的子应用程序可能会与其他内容冲突。例如,我不喜欢django-mutant
如何不命名它是contrib的东西,所以你最终会得到像web
、text
这样的app_labels,它可以用一些东西而不是mutant_web
等来完全类。
然后,当使用外键时,它们将被引用为myapp_subapp1.Bar
,而不是我以前所做的"myapp.subapp1.Bar"