views:

261

answers:

2

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?

+2  A: 

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)
Daniel Roseman
Well, it does not - at least not with webfaction hosting. I'm using mod_wsgi and given a urlpatterns above, the following code"from django.core.urlresolvers import reversepermalink = reverse('myproj.myapp.views.index')" will return "/".Beside that, {% url pinfont.label.views.index %} will give the same path "/".
Dmitry Guyvoronsky
Thank you, I managed to find the reason for the problem myself, but you really helped with .wsgi solution. Small fix - please change 'os.environ' to 'environ' on line 4.
Dmitry Guyvoronsky
A: 

Change:

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

to:

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

Then change the nginx front end configuration of WebFaction to proxy to '/myproj' on back end instead of '/'.

That should be all that is required. You should not use '/myproj' prefix in urls.py.

In other words, just ensure the mount point for back end is same as where it appears mounted at the front end.

Modify WSGI script file to fudge SCRIPT_NAME, although it may work, is not generally recommended as not allowing Apache/mod_wsgi to do the proper thing, which may have other implications.

Graham Dumpleton
Thank you, I'll try this as well
Dmitry Guyvoronsky