Confusing path example for mod_wsgi?

52 views
Skip to first unread message

candlerb

unread,
Jul 4, 2011, 10:49:40 AM7/4/11
to Django users
The example given in `django/docs/howto/deployment/modwsgi.txt` shows:

~~~~
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
...
path = '/path/to/mysite'
if path not in sys.path:
sys.path.append(path)
~~~~

However, when deploying a project I found that I had to include both
the mysite directory and its parent (that is, both `/path/to/mysite`
and `/path/to`), for it to start under Apache, although I didn't have
any problem using `manage.py runserver` when developing. Without this,
apache gave a 500 result and the following in error.log:

[Mon Jul 04 15:38:42 2011] [error] [client 192.168.122.183]
ImportError: Could not import settings 'mysite.settings' (Is it on
sys.path?): No module named mysite.settings

I am running python 2.6.5 under Ubuntu 10.04.2 LTS

Aside: I found that I could make it work with just `/path/to` in
sys.path if I changed my code to qualify all references to
applications, i.e. use `mysite.app1` and `mysite.app2` everywhere
instead of just `app1` and `app2`. But that's messy. In fact, I would
like to be able to remove all references to `mysite` within the code,
but there are a few places it seems to be necessary; in particular,
whenever I want to pull something out of the toplevel SETTINGS file I
end up writing

~~~~
from mysite import settings
~~~~

Am I missing a trick here? If /path/to/mysite is on the path, would it
be safe to use "import settings" instead of "from mysite import
settings" everywhere?

Or should the documentation show both /path/to and /path/to/mysite
being added to the path?

Thanks,

Brian.

Tom Evans

unread,
Jul 4, 2011, 11:29:22 AM7/4/11
to django...@googlegroups.com
On Mon, Jul 4, 2011 at 3:49 PM, candlerb <b.ca...@pobox.com> wrote:
> The example given in `django/docs/howto/deployment/modwsgi.txt` shows:
>
> ~~~~
>    os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
> ...
>    path = '/path/to/mysite'
>    if path not in sys.path:
>        sys.path.append(path)
> ~~~~
>
> However, when deploying a project I found that I had to include both
> the mysite directory and its parent (that is, both `/path/to/mysite`
> and `/path/to`), for it to start under Apache, although I didn't have
> any problem using `manage.py runserver` when developing. Without this,
> apache gave a 500 result and the following in error.log:
>
> [Mon Jul 04 15:38:42 2011] [error] [client 192.168.122.183]
> ImportError: Could not import settings 'mysite.settings' (Is it on
> sys.path?): No module named mysite.settings

However you run django, you must configure the appropriate path
settings so that it can load your modules. If you have setup your
folder layout like this:

/path/to
foo/
settings.py
bar/

Where 'foo' is your project and 'foo.bar' is your app, then you will
need to add /path/to to sys.path.

If on the other hand 'bar' is how you refer to your app, then you will
need to add /path/to/foo to sys.path as well.

>
> I am running python 2.6.5 under Ubuntu 10.04.2 LTS
>
> Aside: I found that I could make it work with just `/path/to` in
> sys.path if I changed my code to qualify all references to
> applications, i.e. use `mysite.app1` and `mysite.app2` everywhere
> instead of just `app1` and `app2`. But that's messy. In fact, I would
> like to be able to remove all references to `mysite` within the code,
> but there are a few places it seems to be necessary; in particular,
> whenever I want to pull something out of the toplevel SETTINGS file I
> end up writing
>
> ~~~~
> from mysite import settings
> ~~~~
>
> Am I missing a trick here? If /path/to/mysite is on the path, would it
> be safe to use "import settings" instead of "from mysite import
> settings" everywhere?
>

You're missing several - you should *never* directly import your
settings like that. The only reliable and approved way to access your
settings is:

from django.conf import settings

Cheers

Tom

candlerb

unread,
Jul 4, 2011, 3:51:20 PM7/4/11
to Django users
On Jul 4, 4:29 pm, Tom Evans <tevans...@googlemail.com> wrote:
> If you have setup your folder layout like this:
> /path/to
> foo/
> settings.py
> bar/
> Where 'foo' is your project and 'foo.bar' is your app, then you will
> need to add /path/to to sys.path.
> If on the other hand 'bar' is how you refer to your app, then you will
> need to add /path/to/foo to sys.path as well.

OK, that's what wasn't clear to me in the documentation. For some
reason, I can refer to 'bar' by itself when using runserver, but with
wsgi I need to add /path/to and /path/to/foo to sys.path (or else
refer to 'foo.bar' everywhere).

> The only reliable and approved way to access your
> settings is:
>
>   from django.conf import settings

Excellent, that makes it a lot tidier.

So now, the only two places I refer to mysite explicitly are:

./django.wsgi:os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
./settings.py:ROOT_URLCONF = 'mysite.urls'

Here's my full django.wsgi, which I have inside the top-level mysite
directory:

~~~~
import os
import sys

path = os.path.dirname(__file__)
if path not in sys.path:
sys.path.append(path)
path = os.path.normpath(os.path.join(os.path.dirname(__file__),".."))
if path not in sys.path:
sys.path.append(path)

os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
~~~~

It still fails if I comment out the second bit of path setup (the ".."
one). However, if I change those two lines to

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'

and

ROOT_URLCONF = 'urls'

then the app does seem to work happily with just /path/to/mysite in
the path. Is this a reasonable thing to do? (I guess only if you ever
have one django project in your path)

Thanks,

Brian.

bruno desthuilliers

unread,
Jul 5, 2011, 5:40:03 AM7/5/11
to Django users
On Jul 4, 9:51 pm, candlerb <b.cand...@pobox.com> wrote:
> OK, that's what wasn't clear to me in the documentation. For some
> reason, I can refer to 'bar' by itself when using runserver, but with
> wsgi I need to add /path/to and /path/to/foo to sys.path (or else
> refer to 'foo.bar' everywhere).

This has to do with 1/ how Python looks for modules (sys.patth), 2/
the fact that your manage.py from the root of your project (and not
from the parent directory) and 3/ some weird things happening with
manage.py and not when running behing apache or another web server.

wrt/ point #1 and #2: Python looks for modules / packages in the path
listed in sys.path, which always start with the current working
directory, so when you're running manage.py from within directory
"foo", foo is first on your sys.path, and you can directly import
'bar'. When running mod_wsgi, if you only adds "/path/to" in your
sys.path, Python will be able to find package "foo" (yes, your Django
project IS a Python package - it has a __init__.py file), and from
this sub-modules (foo.settings) and sub-packages (foo.bar), but NOT
'bar' (there's no package named 'bar' in your sys.path at this
point).

You can either add both '/path/to' and '/path/to/foo' in your sys.path
and point os.environ['DJANGO_SETTINGS_MODULE'] to 'foo.settings' and
settings.ROOT_URLCONF to 'foo.urls', or only add '/path/to/foo' in
your sys.path and point os.environ['DJANGO_SETTINGS_MODULE'] to
'settings' and settings.ROOT_URLCONF to 'urls' (but then any use of
'foo.whatever' will break).

As far as I'm concern I prefer the second solution - I don't want to
have to change anything in my code when I rename my project dir or
move an app to another project or whatever.

wrt/ point #3, I can only point you to Graham Dumpleton's excellent
post:
http://blog.dscpl.com.au/2010/03/improved-wsgi-script-for-use-with.html

bruno desthuilliers

unread,
Jul 5, 2011, 5:46:42 AM7/5/11
to Django users


On Jul 4, 9:51 pm, candlerb <b.cand...@pobox.com> wrote:
> On Jul 4, 4:29 pm, Tom Evans <tevans...@googlemail.com> wrote:
>
> > The only reliable and approved way to access your
> > settings is:
>
> >   from django.conf import settings
>
> Excellent, that makes it a lot tidier.

I think this should be written in big bold letters everywhere in
django's doc...

> Here's my full django.wsgi, which I have inside the top-level mysite
> directory:
>
> ~~~~
> import os
> import sys
>
> path = os.path.dirname(__file__)

you might be better with

path = os.path.dirname(os.path.abspath(__file__))

but anyway; your wsgi file should not be in your project root.

> It still fails if I comment out the second bit of path setup (the ".."
> one). However, if I change those two lines to
>
> os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
>
> and
>
> ROOT_URLCONF = 'urls'

Congratulations <wink>.

> then the app does seem to work happily with just /path/to/mysite in
> the path. Is this a reasonable thing to do? (I guess only if you ever
> have one django project in your path)

Why would you have 2 django projects in your path in this context ?-)

candlerb

unread,
Jul 5, 2011, 6:09:35 AM7/5/11
to Django users
Thanks Tom and Bruno for all the help - my project looks much cleaner
now.
Reply all
Reply to author
Forward
0 new messages