共享django项目结构

Posted

技术标签:

【中文标题】共享django项目结构【英文标题】:shared django project structure 【发布时间】:2019-03-18 02:44:43 【问题描述】:

这就是我的项目的结构。本题将忽略'lib'目录:

project
    app
        data -> migrations, models, __init__.py
        prodsite -> settings.py, urls.py, wsgi.py, __init__.py
        testsite -> same as above
    lib
        data -> migrations, models, __init__.py
        prodsite -> settings.py, urls.py, wsgi.py, __init__.py, common models
        testsite -> same as above
    tools
        manage.py

我希望能够跑步:

python tools/manage.py app.prodsite (makemigrations/migrate) app

修改 manage.py 并不难,将根目录添加到系统路径,将 django 环境变量设置为“app.prodsite”,并从 sys.argv 中删除该参数,然后继续下一步manage.py 通常会。我无法在不导致错误的情况下摆脱最后一个参数:

#!/usr/bin/env python
import os
import sys
import inspect

def main():
    sys.path.append(os.getcwd()) # allow reative to cwd, not just module.py.
    if "DJANGO_SETTINGS_MODULE" not in os.environ:
        if len(sys.argv) < 3:
            print("Error in command: ".format(" ".join(sys.argv)))
            print("manage.py should be called like:\r\n"
                  "manage.py <app> <operation>.")
            return
        os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                              ".settings".format(sys.argv[1]))
        del sys.argv[1]
    try:
        from django.core.management import execute_from_command_line
    except ImportError as exc:
        raise ImportError(
            "Couldn't import Django. Are you sure it's installed and "
            "available on your PYTHONPATH environment variable? Did you "
            "forget to activate a virtual environment?"
        ) from exc
    execute_from_command_line(sys.argv)

if __name__ == "__main__":
    main()

这些是其他相关文件:

# project.app.data:
class M(Model):
    class Meta:
        app_label = 'app.data'
    a: bool
    b: str
    c: float

# project.app.data.apps
class DataConfig(AppConfig):
    name = 'app.data'

# project.app.data.__init__
default_app_config = 'app.data.apps.DataConfig'

# project.app.prodsite.settings
ROOT_URLCONF = 'app.prodsite.urls'
WSGI_APPLICATION = 'app.prodsite.wsgi.application'
INSTALLED_APPS += ['app.data', 'app.micsite']

如果我尝试运行“python bldtool/manage.py app.prodsite makemigrations app.data”,我会收到一条错误消息,询问 app.data 是否在 INSTALLED_APPS 中。

如果我只在 INSTALLED_APPS 中包含“app”,则不会生成错误,但是 django 不会检测到任何更改并且不会生成迁移目录。 (我尝试使用 init.py 创建迁移目录,也没有成功)

我可以做些什么来使这项工作按预期进行?

【问题讨论】:

您使用的是哪个版本的 django?我认为您的 installed_apps 应该类似于 ['app.data.DataConfig'] 。你应该通过 appconfig 类 我使用的是 django 2.0.7。 【参考方案1】:

在这种特殊情况下适合我的配置是:

# project.app.data:
class M(Model):
    class Meta:
        app_label = 'data' # Not full path
    a: bool
    b: str
    c: float

# project.app.data.apps
class DataConfig(AppConfig):
    name = 'app.data'

# project.app.data.__init__
# Empty

# project.app.prodsite.settings
ROOT_URLCONF = 'app.prodsite.urls'
WSGI_APPLICATION = 'app.prodsite.wsgi.application'
INSTALLED_APPS += ['app.data', 'app'] # No need for app.micsite

以上(连同修改后的manage.py)允许我执行:

python tools/manage.py app.prodsite [makemigrations|migrate] data

【讨论】:

【参考方案2】:

根据 django 文档:

指定在此 Django 安装中启用的所有应用程序的字符串列表。每个字符串都应该是一个带点的 Python 路径:

应用程序配置类(首选),或 包含应用程序的包。

此外,迁移目录(其中包含 __init__.py 文件)应在运行 makemigrations 之前创建而不指定应用程序名称,否则,makemigrations 命令不会检测到任何更改。但是如果您指定应用程序名称,即使没有迁移目录,makemigrations 也可以工作。

【讨论】:

我尝试将应用程序路径设置为类,但我仍然收到有关 INSTALLED_APPS 的相同错误,除非我在 INSTALLED_APPS 中拥有整个应用程序目录(在这种情况下,即使有迁移也不会检测到迁移init.py 的目录,在数据目录下) 有效的是:INSTALLED_APPS = ['app.data.apps.DataConfig', 'app'] 我不需要 app/data/__init__.py 也不需要一个空的迁移目录,以生成初始迁移。我现在唯一的抱怨是迁移文件夹位于应用程序而不是应用程序/数据下。我想我可以做到这一点,但是如果您有任何想法可以实现这一点,请告诉我。谢谢! 另一件事是,如果我删除迁移目录并尝试再次运行 makemigrations,输出保持不变 - 未检测到任何更改。我尝试使用 init.py 创建一个空的迁移目录,但这似乎没有什么不同。 如果您指定应用名称,则不再需要迁移目录。因此,如果没有检测到更改,则可能是您的应用程序的路径或其他设置有问题...我建议重新检查 settings.py 文件中的所有设置:) 另外,请检查元类中的 app_label。看看***.com/questions/36153748/…

以上是关于共享django项目结构的主要内容,如果未能解决你的问题,请参考以下文章

django项目创建和结构解释

1Django项目结构

Django 和 'virtualenv' - 正确的项目结构

01_Django-介绍-项目结构-URL和视图函数

01_Django-介绍-项目结构-URL和视图函数

01_Django-介绍-项目结构-URL和视图函数