【问题标题】:Python/Django Standalone Script - Import by filename is not supportedPython/Django 独立脚本 - 不支持按文件名导入
【发布时间】:2018-02-18 12:34:13
【问题描述】:

我有以下脚本,它是一个独立的 Django 脚本,所以我可以从命令行运行 python my_script.py。它曾经与 Django 1.8 一起工作,在我升级到 Django 1.11 后,我收到以下错误:

Traceback (most recent call last):
  File "app.py", line 8, in <module>
    django.setup()
  File "C:\python27\lib\site-packages\django-1.11.5-py2.7.egg\django\__init__.py", line 22, in setup
    configure_logging(settings.LOGGING_CONFIG, settings.LOGGING)
  File "C:\python27\lib\site-packages\django-1.11.5-py2.7.egg\django\conf\__init__.py", line 56, in __getattr__
    self._setup(name)
  File "C:\python27\lib\site-packages\django-1.11.5-py2.7.egg\django\conf\__init__.py", line 41, in _setup
    self._wrapped = Settings(settings_module)
  File "C:\python27\lib\site-packages\django-1.11.5-py2.7.egg\django\conf\__init__.py", line 110, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "C:\python27\lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
ImportError: Import by filename is not supported.

这是我的python脚本

# standalone django setup
import os, sys, logging, django
prj_dir = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
logging.basicConfig(level=logging.INFO)
logging.info("PRJ_DIR: %s" % prj_dir)
sys.path.append(prj_dir)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "%s.settings" % prj_dir.split("/")[-1])
django.setup()

...
...

【问题讨论】:

  • 你能分享你的settings.py吗?因为我无法重现您的问题,并且我怀疑它可能与设置文件有关。提前致谢
  • 您正在使用与 manage.py 位于同一文件夹中的此文件?

标签: python django


【解决方案1】:

在该行中: os.environ.setdefault( "DJANGO_SETTINGS_MODULE", "myproject.settings") # 应该和 import 命令一样 )

只需使用 python 模块路径:如“myproject.settings”而不是 /opt/myproject/settings 或“c:\myproject\settings.py”等路径

【讨论】:

    【解决方案2】:

    不要重新发明轮子。 django 扩展上有一个很酷的管理命令,可让您在 django 上下文中运行脚本。

    https://django-extensions.readthedocs.io/en/latest/runscript.html

    【讨论】:

    • 这可能与 OP 无关,但非常有趣。 (它不会做关于standalone Django script 的问题通常预期的事情。)您的链接与 Burhan Khalid 的“轻量级 Django”链接相结合是鼓舞人心的,可以编写一个简单的脚本,以便使用标签 django-orm 和发布前的 django-queryset:模型、自定义设置和示例在一个文件中,其他所有问题都在另一个文件中 :-)
    【解决方案3】:

    如果你的脚本和settings.py在同一个文件夹,代码应该是这样的:

    import os, sys, logging, django
    prj_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    logging.basicConfig(level=logging.INFO)
    logging.info("PRJ_DIR: %s" % prj_dir)
    sys.path.append(prj_dir)
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{}.settings".format(os.path.basename(prj_dir)))
    django.setup()
    

    否则,如果您的脚本位于 settings.py 的父文件夹中:

    import os, sys, logging, django
    prj_dir = os.path.dirname(os.path.abspath(__file__))
    logging.basicConfig(level=logging.INFO)
    logging.info("PRJ_DIR: %s" % prj_dir)
    sys.path.append(prj_dir)
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{}.settings".format(os.path.basename(prj_dir)))
    django.setup()
    

    【讨论】:

      【解决方案4】:

      其他人指出您的路径操作存在问题,但是您实际导入异常的原因是您将 DJANGO_SETTINGS_MODULE 设置为文件名。

      它必须是 Python 模块的名称。换句话说,您的设置文件应该以.py 结尾,并且您应该传递它的名称(不带.py),或者它的可导入路径——就像您在import 语句中键入它一样。

      如果您的设置在my_settings.py 中,那么您应该将变量设置为my_settings

      这是一个单页 django 应用程序的简化示例,取自出色的 Lightweight Django 书籍excerpt

      import sys
      
      
      from django.conf import settings
      
      
      settings.configure(
          DEBUG=True,
          SECRET_KEY='thisisthesecretkey',
          ROOT_URLCONF=__name__,
          MIDDLEWARE_CLASSES=(
              'django.middleware.common.CommonMiddleware',
              'django.middleware.csrf.CsrfViewMiddleware',
              'django.middleware.clickjacking.XFrameOptionsMiddleware',
          ),
      )
      
      
      from django.conf.urls import url
      from django.http import HttpResponse
      
      
      def index(request):
          return HttpResponse('Hello World')
      
      
      urlpatterns = (
          url(r'^$', index),
      )
      
      
      if __name__ == "__main__":
          from django.core.management import execute_from_command_line
      
          execute_from_command_line(sys.argv)
      

      【讨论】:

      • 您通常是对的,但是很明显 prj_dir 是(应该)通过此代码正确设置所有平台上脚本目录的父目录,没有任何“.py”。如果它是一个 linux 名称,它也被正确拆分,结果是"DJANGO_SETTINGS_MODULE='parentdir.settings'。问题是无效的“\\”字符,但添加的“.py”将是“ImportError: No module named py”。 (感谢轻量级 Django。)
      【解决方案5】:

      错误在

      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "%s.settings" % prj_dir.split("/")[-1])
      

      如果您从与 manage.py 相同的文件夹运行此脚本,它将返回 manage.py 文件夹的名称,而不是 settings.py 文件夹,从而产生 managepy_folder.settings

      何时应该输出 settingspy_folder.settings 以访问应用程序

      测试:

      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settingspy_folder.settings")
      

      如果这是问题所在,如果你想在多个项目中使用相同的算法或类似的东西,你需要一个模式来修改当前文件夹名称以指示 settings.py 文件夹名称,在两个项目中使用相同的文件夹名称不需要修改。

      如果这不能解决,请发布您的 settings.py 文件

      【讨论】:

        【解决方案6】:

        在路径分隔符是反斜杠 \ 的 Windows 上运行脚本时,您似乎试图用正斜杠 / 分割文件路径。使用os.path.basename 而不是手动处理刺痛(.split("/")[-1]):

        >>> import os
        >>> os.path.basename(r'/home/user/project')
        'project'
        >>> os.path.basename(r'c:\users\user\project')
        'project'
        

        比较:

        >>> r'/home/user/project'.split("/")[-1]
        'project'  # works
        >>> r'c:\users\user\project'.split("/")[-1]
        'c:\\users\\user\\project'  # error
        

        【讨论】:

          猜你喜欢
          • 2018-02-10
          • 2016-04-01
          • 2012-02-02
          • 2019-01-29
          • 1970-01-01
          • 2014-11-17
          • 1970-01-01
          • 1970-01-01
          • 2023-03-17
          相关资源
          最近更新 更多