我遇到一个奇怪的问题,希望有人以前遇到过。
我有一个位于my_project/my_app/scripts/custom_script.py
的自定义脚本-我想要的用例是为该脚本提供一个文件路径,并使其处理文件并加载/修改数据库中的某些数据。
这是该脚本的摘录:
import django
def setup_django(env):
if env == 'dev':
settings = "my_project.my_project.dev_settings"
elif env == 'stg':
settings = "my_project.my_project.staging_settings"
elif env == 'prod':
settings = "my_project.my_project.prod_settings"
else:
raise ValueError("Invalid choice for --env argument: {}".format(env))
os.environ.setdefault('DJANGO_SETTINGS_MODULE', settings)
django.setup()
def main():
env = 'dev'
setup_django(env)
# Do stuff with my script
当我在与项目相同的virtualenv中运行以上命令时,出现错误ModuleNotFoundError: No module named 'my_app'
在设置文件中:
...
INSTALLED_APPS = [
'my_app',
'django.contrib.admin',
'django.contrib.auth',
...
]
...
似乎,当我调用django.setup()
时,它会解析我的dev_settings
文件并在my_app
列表中找到INSTALLED_APPS
,然后尝试直接将其导入(例如import my_app
)。这将永远无法工作,因为my_app
是my_project
的子模块(应为import my_project.my_app
)。这是目录结构的示例:
my_project
├── my_project
│ ├── __init__.py
│ ├── dev_settings.py
│ ├── prod_settings.py
│ ├── staging_settings.py
│ ├── urls.py
│ └── wsgi.py
├── my_app
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── models.py
│ ├── scripts
│ │ ├── __init__.py
│ │ ├── **custom_script.py**
│ │ └── utils.py
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── __init__.py
└── manage.py
此设置文件似乎在manage.py
和runserver
中都可以与shell
一起正常工作(可以找到my_app
应用程序)。但是在custom_script.py
内部似乎全部消失了。
有什么想法吗?
答案 0 :(得分:4)
使用management commands将自定义脚本添加到您的应用中,以便正确加载所有django配置。
在您的my_app
文件夹中,在下面创建文件夹结构
management/
__init__.py
commands/
__init__.py
my_command.py
在my_command.py
from django.core.management import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
print('running custom command')
在您的外壳上
python manage.py my_command