Search code examples
pythondjangovirtualenvbuildout

Buildout installs django but can't import


Here's my buildout.cfg:

[buildout]
parts =
    django

[versions]
djangorecipe = 1.5
django = 1.7

[django]
recipe = djangorecipe
project = timetable
eggs = 

Here's my routine for setting up project in a new environment:

virtualenv .
source bin/activate
easy_install -U setuptools
python bootstrap.py
bin/buildout -v
python manage.py migrate

When I run bin/buildout, it says django is installed, and django binary is in the bin folder. But when I run manage.py, it can't import django:

(timetable)mick88@s59gr2dmmd:~/timetable$ python manage.py migrate
Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from django.core.management import execute_from_command_line
ImportError: No module named django.core.management

But it works when I install django using pip. Why doesn't buildout install django in my virualenv? How can I fix this?


Solution

  • Buildout doesn't install anything in a virtualenv. Buildout collects python packages and adds programs to the bin/ directory that have the correct python packages added to their sys.path.

    So:

    • virtualenv/pip installs everything into the virtualenv. You have to activate the virtualenv so that it can modify your PYTHONPATH environment variable (and the PATH variable). This way the python from your virtualenv's bin/ directory is used and the python packages from the lib/ dir.

    • Buildout adds the necessary "pythonpath" changes to scripts in bin/, modifying the sys.path setting directly instead of through the environment variable.

    The one thing you need to know is that you should run bin/django instead of python manage.py. The effect is the same, only bin/django already has the right sys.path setting.

    As an example, just look at the contents of the bin/django script. It should look something like this:

    #!/usr/bin/python
    
    import sys
    sys.path[0:0] = [
      '/vagrant',
      '/vagrant/eggs/djangorecipe-1.10-py2.7.egg',
      '/vagrant/eggs/Django-1.6.6-py2.7.egg',
      '/vagrant/eggs/zc.recipe.egg-2.0.1-py2.7.egg',
      '/vagrant/eggs/zc.buildout-2.2.1-py2.7.egg',
      '/vagrant/eggs/South-1.0-py2.7.egg',
      ...
      ]
    
    import djangorecipe.manage
    
    if __name__ == '__main__':
        sys.exit(djangorecipe.manage.main('yoursite.settings'))