Thursday, June 18, 2009

Django, Apache 2.2, mod_ssl, and mod_wsgi (Part 3)

Part 1 | Part 2 | Part 3

Serving up Django
Following the completion of Part 2, we have an install of Django and Apache, and 2 virtual hosts running on it. What we need to do is connect those virtual hosts up to the content we need to serve.

Before we can do that, we need to add our Django app to the server. Create a folder on your webserver (anywhere really) that isn't in your document root (don't use htdocs). In my case I just made a folder off of the drive "Root_Django". Copy your django app folder into there. You should end up with something like...

C:\Root_Django\{nameofyourwebapp}

To connect Django up to Apache, we need to create a python file that will initialize WSGI and pass that information on to Django. In your {nameofwebapp} folder, create a sub folder named "apache", and then create a new file in that folder named "django.wsgi".

Paste this script into that file:

import os, sys
sys.path.append('C:\\Root_Django')
sys.path.append('C:\\Root_Django\\{nameofwebapp}')
os.environ['DJANGO_SETTINGS_MODULE'] = '{nameofwebapp}.settings'

# Remap stdout to err
sys.stdout = sys.stderr

import django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
Be sure of course to change "{nameofwebapp}" to the actual name of your django application. This short script will take care of a few things...
  • the sys.path.append portion needs to point to your actual Django root. Adjust that if it's not C:\Root_Django
  • sys.stdout = sys.stderrd will redirect all "print" statements to the Apache error log. If you don't have any print statements in your code you can drop this, but I prefer to keep it "just in case"
This script will take care of initializing Django. All we need to do is connect up the requests to our apache virtual host to this script. Edit httpd.confi, and inside of the virtual host for your "www" host, add these lines:
WSGIScriptAlias / C:\Root_Django\{nameofwebapp}\apache\django.wsgi

<Directory "C:\Root_Django\{nameofwebapp}">
Order deny,allow
Allow from all
</Directory>
This tells Apache that all requests coming in from / and up should be handled through the django.wsgi script. Save your httpd.conf file and restart Apache. You should see your Django app being served up now, minus the media (images, css, etc.).

Serving up Static Media
So you're serving python now, but your web app without images and css is pretty limp right?

Here's what we need to do:
  • Configure an Apache virtual host to serve our static media
  • Configure Django to know the correct place for our media
  • Make sure we're also serving the grappelli media instead of the default admin media
Open up your httpd.conf file again, and find the Virtual host for your media.example.com (or whatever your static host name is). Since this will just be basic serving without WSGI, we simply need to configur the document root to the proper location...
DocumentRoot "C:\Root_Django\{nameofwebapp}\media"
<Directory "C:\Root_Django\{nameofwebapp}\media">
Order deny,allow
Allow from all
</Directory>
Tada! If you were to save and restart apache, then navigation to media.example.com/some/css/file.css it should work. What we still need is to serve up the grappelli media. To do this we'll add another alias so that media.example.com/admin will serve the grappelli content.
Alias /admin "C:\Root_Django\{nameofwebapp}\grappelli\media"

<Directory "C:\Root_Django\{nameofwebapp}\grappelli\media">
Order deny,allow
Allow from all
</Directory>
This will make sure that all requests to /admin on your media host will serve the grappelli media files. If you installed grappelli into your Python site-packages folder, be sure to set the path to that folder instead of the django root like shown above.

Configure Django With Media Prefixes
Lastly for this section, we need to do some configuration in Django.

In Part 1 we installed grappelli but we haven't configured it, so we'll do that now. Also, we're using a static media virtual host, so we need to make sure that Django is prefixing our media files correctly. All of this takes place in the settings.py file.

Configure grappelli
If you'd rather see the officiall grappelli installation instructions, they are available on the grappelli google code wiki.

First, add grappelli to the content processors:

TEMPLATE_CONTEXT_PROCESSORS = (
"django.core.context_processors.auth",
"django.core.context_processors.request",
"grappelli.context_processors.admin_url",
)
Next, add the grappelli template directory:

import os
here = lambda x: os.path.join(os.path.abspath(os.path.dirname(__file__)), x)
TEMPLATE_DIRS = (
# ...
here('grappelli/templates/'),
)
Lastly, of course, add grappelli to your list of installed apps:

INSTALLED_APPS = (
# ...
'grappelli',
)
Configure Media Prefixes
We want to configure Django to automatically insert "http://media.example.com/" in front of all of our media files. The setting in the settings.py to do this is:

MEDIA_URL = 'http://media.example.com/'
But this could easily become problematic when we're testing django with runserver. A better result would be to conditionally test if we're in DEBUG mode, and to change the value based on that.
if DEBUG:
MEDIA_URL = '/media/'
else:
MEDIA_URL = 'http://media.example.com/'
We'll also want to make sure the admin media files from grappelli are being served. The code is almost identical, expect the setting is ADMIN_MEDIA_PREFIX:
if DEBUG:
ADMIN_MEDIA_PREFIX = '/grappelli/media/'
else:
ADMIN_MEDIA_PREFIX = 'http://media.example.com/admin/'
At this point Django should be running, and serving media files.

Still to come:
  • Configuring HTTPS
  • Forcing HTTPS for django admin

0 comments:

  © Blogger template 'Minimalist G' by Ourblogtemplates.com 2008

Back to TOP