【问题标题】:Using Django models in external python script在外部 python 脚本中使用 Django 模型
【发布时间】:2013-10-20 09:41:46
【问题描述】:

我今天很迷茫。

我试图在我的 python 脚本中使用我的 django 应用程序模型。

这是我的方法

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
from django.contrib.auth.models import User

我很困惑为什么它给我

ImportError: Could not import settings 'openstack_dashboard.settings' (Is it on sys.path?): cannot import name auth

检查后我创建了一个名为 creds 的文件,其中包括

export PYTHONPATH=$PYTHONPATH:/var/www/cloudloon/horizon/; 
export DJANGO_SETTINGS_MODULE=openstack_dashboard.settings; django-admin.py shell;

从 creds 文件所在的终端窗口,我会这样做

source creds

从那个 django-admin.py shell,我可以导入我的任何 django 应用程序模型而不会出现任何错误。

为什么它在我的 python 脚本中不起作用?

我已经完成了 Django,我需要做的是创建一个 python-daemon 脚本来访问我的 django 应用程序模型。

我正在使用具有 django 1.5 的 Ubuntu 12.04

在寻找解决方案时,我这样做了:

import os, sys

sys.path.append("/var/www/cloudloon/horizon")
sys.path.append("/var/www/cloudloon/horizon/openstack_dashboard")
# os.environ["DJANGO_SETTINGS_MODULE"] = "settings"
os.environ.setdefault("DJANGO_SETTINGS_MODULE",
                          "openstack_dashboard.settings")

print os.environ["DJANGO_SETTINGS_MODULE"]
for s in sys.path:
    print s

from django.contrib.auth.models import User

输出如下:http://paste.openstack.org/show/48787/

如您所见,我的 sys.path 中存在 settings.py 所在的目录,但是,仍然无法导入 openstack_dashboard.settings。

谢谢大家。

【问题讨论】:

    标签: python django


    【解决方案1】:

    我的解决方案(灵感来自http://blog.gabrielsaldana.org/using-django-models-in-external-python-scripts/):

    import os
    import sys
    sys.path.append( os.path.join(os.path.dirname(__file__), 'MyDjangoProject'))
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MyDjangoProject.settings")
    import django
    from django.conf import settings
    django.setup()
    
    from myapp.models import MyModel
    for s in MyModel.objects.all():
        print(s) 
    

    【讨论】:

      【解决方案2】:

      如果您的项目布局(以及设置文件的路径)如下所示,则以下脚本应该可以工作:

      /var/www/cloudloon/horizo​​n/openstack_dashboard/settings.py

      #!/usr/bin/env python
      import os, sys
      
      sys.path.append("/var/www/cloudloon/horizon")
      os.environ["DJANGO_SETTINGS_MODULE"] = "openstack_dashboard.settings"
      from django.contrib.auth.models import User
      

      我相信您看到的问题是由于您的项目的安排,或者您需要将另一个目录级别附加到脚本中的 sys.path 调用。

      编辑:

      查看您的 github 项目,horizonopenstack_dashboard 位于同一目录级别。您想要做的是将您的 sys.path 设置为更高一级:

      sys.path.append("/var/www/cloudloon")
      

      【讨论】:

      • 管理命令对于我要创建的内容似乎不是一个好主意。我需要创建 python-daemon 脚本。基本上,要运行 python-daemon 脚本,我需要运行“python myscript.py run”。 Python管理命令对它不好。
      • 使用上面的代码,它给了我 AttributeError: 'str' object has no attribute 'file'
      • @DjangoBot 抱歉,setup_environ 采用模块对象,而不是字符串。我已经更正了代码 sn-p。
      • setup_environ 自 Django 1.4 以来似乎已被弃用。弃用警告:“setup_environ”功能已弃用,您可能需要更新“manage.py”;请参阅 Django 1.4 发行说明 (docs.djangoproject.com/en/dev/releases/1.4)
      • @DjangoBot 我已经更新了我的答案,但它基本上只是说检查你的项目结构。
      【解决方案3】:

      这对我有用:

      from django.conf import settings
      import myfolder.settings as app_settings
      
      settings.configure(INSTALLED_APPS=app_settings.INSTALLED_APPS,DATABASES=app_settings.DATABASES)
      
      import django
      django.setup()
      
      from myapp123.models import Sample
      for s in Sample.objects.all():
          print(s)
      

      【讨论】:

        【解决方案4】:

        你需要写一个custom management command,而不是做这些奇怪的杂技。

        在@987654327 中列出的任何应用程序的目录中创建一个名为管理的模块(换句话说,创建一个目录management 并在其中创建一个空的__init__.py 文件) @。所以如果你有myapp,你会创建:

        myapp
         |
         > management
         | | __init__.py
         > models.py
         > views.py
        

        然后在管理目录中,创建另一个模块commands,并在其中创建一个文件,该文件是您的命令名称;比如my_command.py,像这样:

        myapp
         |
         > management
         | | __init__.py
         | | commands
         | | | __init__.py
         | | | my_command.py
         > models.py
         > views.py
        

        my_command.py 中,编写以下样板代码:

        from django.core.management.base import BaseCommand, CommandError
        from myapp.models import MyModel
        
        class Command(BaseCommand):
            help = 'Does some magical work'
        
            def handle(self, *args, **options):
                """ Do your work here """
                self.stdout.write('There are {} things!'.format(MyModel.objects.count()))
        

        保存文件后,您将能够执行python manage.py my_command,它将可以访问您的所有模型和设置。

        如果您需要将它作为守护程序运行,Daniel Roseman 写了 django-initd,它就是这样做的。安装后:

        from django.core.management.base import CommandError
        from daemon_command import DaemonCommand
        from myapp.models import MyModel
        
        class Command(DaemonCommand):
            help = 'Does some magical work'
        
            def loop_callback(self, *args, **options):
                """ Do your work here """
                self.stdout.write('There are {} things!'.format(MyModel.objects.count()))
        

        一旦你完成了from the github readme:

        The important parts of such a process are these:
        
            * it comes up automatically on server startup
            * it logs errors and information to a named location, which is configurable
            * if the process dies, it restarts itself straight away 
        
        [...]
        
        Run the command as normal, but pass one of --start, --stop or --restart to 
        work as a daemon. Otherwise, the command will run as a standard application.
        

        【讨论】:

        • 我以前有这个答案,但脚本应该是一个守护进程,而不是一次性命令。
        • 用python-daemon实现好像太难了。
        • 很好的答案,不知道 django-initd。 OP应该这样做,但我认为OP存在路径问题。
        • 一旦他使用管理命令,路径问题就会消失。
        • 这在 Django 1.8 上完美运行。 (其他答案中建议的路径设置和导入技术均无效。)
        猜你喜欢
        • 1970-01-01
        • 2019-05-31
        • 2013-10-21
        • 1970-01-01
        • 2021-12-30
        • 2016-02-20
        • 2015-11-12
        • 1970-01-01
        • 2014-06-04
        相关资源
        最近更新 更多