简体   繁体   中英

How do I get my Django manage.py working properly when the files are accessed through a symlink?

Problem

When trying to run one of my custom Django management commands ( send_notify_emails ), I get the following error:

$ 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

Background

I have a Django site with two apps in it. The path to the site directory (which includes the app module directories, as well as settings.py, urls.py and manage.py) is /srv/web_apps . This is a symbolic link to /usr/share/my_django_app-1.0 , which is an svn export of a production release tag. This way I can change my app version over by just moving the symbolic link to the path for the new production version, and easily change back to an earlier release if I need to.

My django.wsgi file adds /srv and /srv/web_apps to the Python path so that mod_wsgi can find my settings and url files, as well as the app modules.

The ONLY place that my_django_app-1.0 appears is the directory path, it is not anywhere in my settings.py or otherwise, so Django must be getting the module name from the path.

What seems to be happening is Django is resolving the package name for my app by following the symbolic link and using the name of the target folder, instead of the symbolic link itself. When I run manage.py , Django tries to import my_django_app-1.0 when it should be importing web_apps .

I have a Django site with two apps in it. The path to the site directory (which includes the app module directories, as well as settings.py, urls.py and manage.py) is /srv/web_apps. This is a symbolic link to /usr/share/my_django_app-1.0, which is an svn export of a production release tag. This way I can change my app version over by just moving the symbolic link to the path for the new production version, and easily change back to an earlier release if I need to.

What you're describing is basically the exact reason why people like virtualenv so much. I'd suggest taking a read through of mod_wsgi Virtual Environments .

The issue is that __file__ is returning the symlink a relative path which depending on where it's being imported from (inside a symlink'd path..), thats how it'll report it's home. Since directories are the basic structure of modules, if you have a directory with __init__.py in it, then whatever that directory is named will be the ' name ' if you import it.

You might be able to override this behavior, but that'd be the wrong way to go about things - check out virtualenv, or setup separate directories per version and just use underscores instead of periods. myApp_1_0_0 , etc.

Consider the following scenario

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM