3

I have deployed a Django project on an Apache server using mod_wsgi, using a prefix URL /mysite, i.e. my Apache configuration contains

WSGIScriptAlias /mysite /var/www/mysite/mysite/wsgi.py

When reverse('myview') (from django.core.urlresolvers) is called from the web server process, it returns the expected URL /mysite/myview, i.e. including the prefix URL.

However, when reverse('myview') is called from a script (e.g. a cronjob), not through the web server process, only /myview is returned without the desired prefix URL. My example script looks like this:

import sys
import os
import django

sys.path.append('/var/www/mysite')
os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
django.setup()

from django.core.urlresolvers import reverse
print reverse('myview') # prints '/myview'

Is there a way to include the prefix URL when running outside of the web server context, so that the same reverse('myview') code can be run from both contexts and returns the same value?

Jens Wetzl
  • 45
  • 3
  • While not an exact duplicate (WSGI vs. regular python script, as opposed to Django shell vs. regular python script), the solutions to http://stackoverflow.com/q/4847469/674064 might apply here, too. – das-g Sep 01 '15 at 21:13
  • 1
    Use `FORCE_SCRIPT_NAME` setting – mingaleg Sep 01 '15 at 21:18
  • I tried adding `FORCE_SCRIPT_NAME = '/mysite'` in `settings.py`, but it makes no difference to the output of `reverse('myview')` when called from a script. – Jens Wetzl Sep 01 '15 at 21:33

1 Answers1

3

Django only expects a SCRIPT_NAME in the context of a web request. It is retrieved from the WSGI environment or the FORCE_SCRIPT_NAME setting and set for the duration of the request.

To manually set a script name, use set_script_prefix():

from django.core.urlresolvers import set_script_prefix

set_script_prefix('/mysite')

Note that this is 1) a private, undocumented function, and 2) stored in a thread-local variable.

knbk
  • 52,111
  • 9
  • 124
  • 122
  • 1
    This does work, so I'll accept the answer. However, it would be nicer not to have to resort to an undocumented function. Is there a reason that there isn't a nicer way, i.e. am I using `reverse` in a way I shouldn't? My use case is a cronjob which sends emails containing links to the web site, which should obviously contain the correct prefix URL. – Jens Wetzl Sep 01 '15 at 22:30