Search code examples
pythondjangourlproduction-environment

Webfaction apache + mod_wsgi + django configuration issue


A problem that I stumbled upon recently, and, even though I solved it, I would like to hear your opinion of what correct/simple/adopted solution would be.

I'm developing website using Django + python. When I run it on local machine with "python manage.py runserver", local address is http://127.0.0.1:8000/ by default.

However, on production server my app has other url, with path - like "http://server.name/myproj/"

I need to generate and use permanent urls. If I'm using {% url view params %}, I'm getting paths that are relative to / , since my urls.py contains this

urlpatterns = patterns('',
 (r'^(\d+)?$', 'myproj.myapp.views.index'),
 (r'^img/(.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT + '/img' }),
 (r'^css/(.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT + '/css' }),
)

So far, I see 2 solutions:

  1. modify urls.py, include '/myproj/' in case of production run
  2. use request.build_absolute_uri() for creating link in views.py or pass some variable with 'hostname:port/path' in templates

Are there prettier ways to deal with this problem? Thank you.

Update: Well, the problem seems to be not in django, but in webfaction way to configure wsgi. Apache configuration for application with URL "hostname.com/myapp" contains the following line

WSGIScriptAlias / /home/dreamiurg/webapps/pinfont/myproject.wsgi

So, SCRIPT_NAME is empty, and the only solution I see is to get to mod_python or serve my application from root. Any ideas?


Solution

  • You shouldn't need to do anything special. Django honours the SCRIPT_NAME environment variable that is set by mod_wsgi when you serve a Django site other than from the root, and prepends it to the url reversing code automatically.

    If you're using mod_python (you shouldn't be), you may need to set django.root in your Apache configuration.

    Updated I suspect this is due to the way that Webfaction serves Django sites via a proxy instance of Apache - this instance has no knowledge of the actual mount point as determined by Webfaction's control panel.

    In this case, you'll probably need to set SCRIPT_NAME manually in your .wsgi script. I think this should work:

    _application = django.core.handlers.wsgi.WSGIHandler()
    
    def application(environ, start_response):
        os.environ['SCRIPT_NAME'] = '/myproj/'
        return _application(environ, start_response)