Django can be run under any WSGI server, which means you can use it in a WSGI pipeline. Deploying Django under mod_wsgi is well documented, but sometimes you want to test your WSGI pipeline on a local server without mucking with configuring nginx or apache, and/or try out some WSGI development tools that you don't want to accidentally put on your production config.
Paste Deploy is a nice little WSGI server that we can use for this purpose, but I didn't find any existing tutorials for running Django under it, hence this post.
First, you'll need a python file that defines a WSGI application for your Django app. This can be the same as you would use for deploying under mod_wsgi; so, see the docs for that. Here's mine:
import os
import sys
import site
os.environ['DJANGO_SETTINGS_MODULE'] = 'foo.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/foo-python-eggs'
# I use VirtualEnv a lot; need to get its site-packages onto the path.
env_root = '/home/pw/hacking/foo-environ'
#####################################################################
# End of configurable stuff. Below shouldn't need to be edited.
# Some libraries (eg. geopy) have an annoying habit of printing to stdout,
# which is a no-no under mod_wsgi.
# Workaround as per http://code.google.com/p/modwsgi/wiki/ApplicationIssues
sys.stdout = sys.stderr
sitepackages_root = os.path.join(env_root, 'lib')
for d in os.listdir(sitepackages_root):
if d.startswith('python'):
site.addsitedir(
os.path.join(sitepackages_root, d, 'site-packages')
)
break
else:
raise RuntimeError(
"Could not find any site-packages to add in %r" % env_root
)
import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
You'll need to add one more thing to that file: an app_factory function as per the Paste Deploy docs:
def app_factory(global_config, **local_conf):
return application
Now, to test this, write a minimal development.ini file:
[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8000
[app:main]
paste.app_factory = mypackage.my_wsgi_module:app_factory
That configures the paste server and loads your Django app as the main application.
Now try firing things up:
$ paster serve development.ini
Starting server in PID 4898.
serving on http://127.0.0.1:8000
Browse to http://localhost:8000
and make sure it works.
Middleware
There's a couple ways we could add middleware.
For middleware that is necessary to the application, I'm going to
assume that we will be deploying under mod_wsgi
, and so the middleware
can be set up by manually wrapping the application object in our
python WSGI script. That way it'll be used both in production and
development regardless of what WSGI server we use.
But for development purposes, sometimes you want to use some
middleware that isn't appropriate to a production deployment. For
that, it's probably more sane to edit our development.ini
file.
As an example, let's try some profiling with the dev version of Dozer, as suggested by http://mg.pov.lt/blog/profiling-with-dozer. Let's install it:
$ pip install -e hg+http://bitbucket.org/bbangert/dozer#egg=Dozer
Now let's configure it as a filter in development.ini:
[server:main]
use = egg:Paste#http
host = 127.0.0.1
port = 8000
[pipeline:main]
pipeline = dozer django
[app:django]
paste.app_factory = mypackage.my_wsgi_module:app_factory
[filter:dozer]
use = egg:Dozer#profile
profile_path = /tmp/profiles
Re-start the dev server and check out Dozer's profiling at http://localhost:8000/_profiler/showall