当通过符号链接访问文件时,如何让我的Django manage.py正常工作?

时间:2011-05-03 21:19:21

标签: python django linux symlink

问题

尝试运行我的一个自定义Django管理命令(send_notify_emails)时,出现以下错误:

$ python web_apps/manage.py send_notify_emails
Traceback (most recent call last):
  File "web_apps/manage.py", line 11, in <module>
    execute_manager(settings)
  File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 436, in execute_manager
    setup_environ(settings_mod)
  File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 419, in setup_environ
    project_module = import_module(project_name)
  File "/usr/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
ImportError: No module named my_django_app-1.0

背景

我有一个Django网站,里面有两个应用程序。站点目录的路径(包括app模块目录,以及settings.py,urls.py和manage.py)是/srv/web_apps。这是/usr/share/my_django_app-1.0的符号链接,svn export是生产版本标记的django.wsgi。这样我就可以通过将符号链接移动到新生产版本的路径来更改我的应用程序版本,如果需要,可以轻松更改回早期版本。

我的/srv文件将/srv/web_appsmod_wsgi添加到Python路径中,以便my_django_app-1.0可以找到我的设置和网址文件以及应用模块。

settings.py出现的唯一地方是目录路径,它不在我的manage.py或其他任何地方,因此Django必须从路径中获取模块名称。

似乎正在发生的事情是Django通过遵循符号链接并使用目标文件夹的名称而不是符号链接本身来解析我的应用程序的包名称。当我运行my_django_app-1.0时,Django会在导入web_apps时尝试导入{{1}}。

1 个答案:

答案 0 :(得分:3)

  

我有一个Django网站,里面有两个应用程序。网站的路径   目录(包括应用程序模块目录,以及   settings.py,urls.py和manage.py)是/ srv / web_apps。这是一个   符号链接到/usr/share/my_django_app-1.0,这是一个svn导出   生产发布标签。这样我可以更改我的应用程序版本   只需将符号链接移动到新生产的路径即可   版本,如果需要,可以轻松更改回早期版本。

你所描述的基本上是人们如此喜欢virtualenv的确切原因。 我建议你仔细阅读mod_wsgi Virtual Environments

问题是__file__正在为符号链接返回依赖的相对路径 在它从哪里导入(在符号链接的路径...内),这就是它将如何报告 它是家。由于目录是模块的基本结构,因此如果您有目录 其中包含__init__.py,无论该目录被命名为“名称” 如果你导入它。

您可能可以覆盖此行为,但这是错误的方法 事情 - 检查virtualenv,或每个版本设置单独的目录,只是使用 强调而不是句号。 myApp_1_0_0

考虑以下情况

mkdir real_directory
ln -s real_directory symlink_directory
cat >>real_directory/__init__.py <<EOF
import os
print
print '__name__ == %s' % (__name__)
print '__file__ == %s' % (__file__)
print ' abspath == %s' % os.path.abspath(__file__)
print 'realpath == %s' % os.path.realpath(os.path.abspath(__file__))
print
EOF

python -c“import real_directory”

__name__ == real_directory
__file__ == real_directory/__init__.py
 abspath == /Users/nar/pt/real_directory/__init__.py
realpath == /Users/nar/pt/real_directory/__init__.py

python -c“import symlink_directory”

__name__ == symlink_directory
__file__ == symlink_directory/__init__.pyc
 abspath == /Users/nar/pt/symlink_directory/__init__.pyc
realpath == /Users/nar/pt/real_directory/__init__.pyc