如何在Django项目的上下文中执行任意脚本?

时间:2011-06-11 20:51:31

标签: python django django-testing django-command-extensions

有时候我想在我的Django项目的上下文中执行一个文件,就像我使用shell一样,但是方便使用文本编辑器。这主要是为了尝试一些东西,或者在将其放入视图,测试,重复任务或管理命令之前快速构建一些功能原型。

我知道我可以将这些行放在我的.py文件的顶部,它将在Django上下文中运行:

import sys
sys.path.append('/location/of/projet')
from django.core.management import setup_environ
import settings
setup_environ(settings)

我认为制作一个带有参数的管理命令,运行python模块并在Django环境中执行它会更容易。这是我写的'runmodule'命令:

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = "Runs an arbitrary module, in the Django environment, for quick prototyping of code that's too big for the shell."

    def handle(self, *args, **options):
        if not args:
            return
        module_name = args[0]

        try:
            __import__(module_name)
        except ImportError:
            print("Unable to import module %s.  Check that is within Django's PYTHONPATH" % (module_name))

这看起来很有效 - 我可以在模块中粘贴一些代码,并将其作为参数传递给此命令,它将被执行,例如。

python manage.py runmodule myapp.trysomethingout

将执行myapp / trysomethingout.py。这是最好的方法吗?

3 个答案:

答案 0 :(得分:9)

使用正确的django上下文执行脚本的最佳方法是将DJANGO_SETTINGS_MODULE环境变量设置为您的设置模块(如果需要,还可以设置适当的PYTHONPATH)。在Windows中,这通常意味着执行:

set DJANGO_SETTINGS_MODULE=setting 

和bash:

export DJANGO_SETTINGS_MODULE=setting 

您现在可以导入模型等。

请参阅:https://docs.djangoproject.com/en/dev/topics/settings/#designating-the-settings

请注意,要导入settings模块,应使用from django.conf import settings。这会考虑DJANGO_SETTINGS_MODULE,而不是自动使用settings.py。

答案 1 :(得分:1)

这是最简单的解决方案:

import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

import django
django.setup()

在导入任何模型之前,请确保在python文件的顶部中包含此内容。

或者,您可以使用@beyondfloatingpoint指出的解决方案:

import os, sys

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")
sys.path.append("mysite")
os.chdir("mysite")
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

答案 2 :(得分:0)

this文章中提供了最佳解决方案。

提示:确保使用正确的设置模块路径,在本例中,我错过了以相同方式命名的嵌套目录。避免我犯错的最好方法是使用类似this的模板开始。