I’ve been toying around with some small ideas for websites, and I’ve been looking for some straightforward frameworks that would allow me to quickly prototype a site that could still be used, at least for moderate levels of traffic, in a production environment. I decided to check out Django, a Python based web framework that supports a lot of out-of-the-box functionality and is easily extensible.
This post outlines the steps I took to install Django on test web server, which is currently running Ubuntu 10.10 (Maverick Meerkat).
As is often the case, I like to configure my test system so that it is as close as possible to the production environment I eventually deploy to. In many cases, that means deviating from Ubuntu’s distribution repositories and installing some packages from source. In the case of Django, there is an appliance version of Ubuntu that supports Django, but nothing official in the repositories. So as usual, I’m back to installing my own version. Before I started, I laid out a few of the requirements I would like to achieve.
- Use the latest stable version of Django (1.2.3)
- Install Django in a shared location, but Django sites should be independent.
- Each Django site should be in its own Apache VirtualHost, so as not to disturb the other sites I have running on my test server.
- Each Django site should be easily maintained in source control and should not include any major artifacts from the Django library. This will make the application portable, and will be helpful when I move it to other servers, such as production.
I based most of my work on an article on jeffbaier.com, but made some adjustments along the way to suit my needs, so I’m posting my steps for anyone else that might be following the same path.
Conceptually, you can break down installing Django into the following steps:
- Retrieve and Install Django
- Create and Configure a Django project
- Configure Apache
- Get coding on your new Django installation
Retrieve and Install Django
In order to retrieve and install Django, I directly checked out the stable branch from Django’s SVN repository. I put it in my /usr/share directory, as it is a shared library used by the system. In addition to checking out the library, I set permissions so that it was owned by the www-data user (my apache user) and linked the Django package into my python library. I also linked the django-admin.py script into my bin directory so that it is always available on the path. The steps for doing this are illustrated below.
# check out version 1.2.3 of Django into my /usr/share directory and update permissions sudo svn co http://code.djangoproject.com/svn/django/tags/releases/1.2.3/ /usr/share/django sudo chown -R www-data:www-data /usr/share/django # link Django package into the python library sudo ln -s /usr/share/django/django /usr/lib/python2.6/dist-packages/django # make django-admin.py available on the path sudo ln -s /usr/share/django/django/bin/django-admin.py /usr/local/bin/django-admin.py
If you are unsure of where Python is installed on your system, you can get this by running the following line.
python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
That’s all that’s needed. You’re now ready to move on to creating your first Django project.
Create and Configure a Django project
Set up the Database
Before you start, you should set up a database for Django to use. I use MySql, but there are a number of compatible databases and non-database backends that can be used with Django. My database setup is pretty simple. Just log into mysql as root
mysql -u root - p
and then run the following commands
CREATE DATABASE mydjango; CREATE USER 'mydjango'@'localhost' IDENTIFIED BY 'mydjango' CREATE USER 'mydjango'@'%' IDENTIFIED BY 'mydjango' GRANT ALL PRIVILEGES ON mydjango.* to 'mydjango'@'%' WITH GRANT OPTION; GRANT ALL PRIVILEGES ON mydjango.* to 'mydjango'@'localhost' WITH GRANT OPTION; FLUSH PRIVILEGES;
Creating the Django Site
Next up is creating the Django site. Django provides an admin script for creating the project for you, so I only had to choose a directory for where the site would live, and set up the directory structure that I wanted to use.
For my purposes, I wanted my site to live under /var/www, but still be owned by me. This would allow me eventually to check the site directory under /var/www directly into SVN. That way, on my test system, I can work directly on the files on the server and check in changes directly to SVN. Additionally, I can work remotely, and synch the latest changes onto the test server easily via an SVN up.
The directory structure I chose was a follows:
- django_projects – The directory I will create my projects in. Using this model, my site can actually be made up of multiple django projects if needed.
- django_templates – A directory of templates that all Django projects in my site will use.
- media – A directory where common media (jpgs, gifs, pngs, etc.) will be stored. These eventually will be accessed outside of the Django framework to reduce overhead.
- admin_media – A directory that is actually a symbolic link back to the admin_media directory in the main Django library. This allows the auto-generated admin module to use its resources.
The steps I followed for setting this up were
#create directories sudo mkdir /var/www/mydjango/django_projects sudo mkdir /var/www/mydjango/django_templates sudo mkdir /var/www/mydjango/media #link in the admin media sudo ln -s /usr/share/django/django/contrib/admin/media /var/www/mydjango/admin_media #set up ownership so I own the directory. Make sure www-data still has rx access via group permissions sudo chown -R tom:tom /var/www/mydjango
The next step is to create a new django project. Django comes with a django-admin.py script (which I’ve already added to the path) that allows you to easily setup a project. This is just a two-liner, switch to right directory and create the project.
cd /var/www/mydjango/django_projects django-admin.py startproject mydjango
With the script all our files have been created, the next step is to configure Django. First you will modify the /var/www/mydjango/django_projects/mydjango/settings.py file. I’ve included my file below, but the key areas you want to modify are:
- Add yourself in the ADMINS section
- Add the correct database to the DATABASES section (my example shows mysql)
- Set the TIME_ZONE for your server
- Change MEDIA_ROOT to be the location on disk where your media will reside (the media directory we set up before)
- Change MEDIA_URL to be the URL where media will be accessed from.
- Change ADMIN_MEDIA_PREFIX to be the relative URL from the site root where the admin media will be accessed from.
- Update the SECRET_KEY to something random (this is to randomize any hash and crypto functions for security purposes)
- Update ROOT_URLCONF to reference the urls.py file in your project directory.
- Add your templates directory (the one created earlier) to the TEMPLATE_DIRS list
- Enable the admin interface in INSTALLED_APPS by uncommenting ‘django.contrib.admin’
My final is shown below for reference.
You’ll also want to update your urls.py to enable the admin urls. Update your /var/www/mydjango/django_projects/mydjango/urls.py to match the file I have below. The updates I made were to uncomment lines 4,5 and 15.
from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin admin.autodiscover() urlpatterns = patterns('', # Example: # (r'^mydjango/', include('mydjango.foo.urls')), # Uncomment the admin/doc line below to enable admin documentation: # (r'^admin/doc/', include('django.contrib.admindocs.urls')), # Uncomment the next line to enable the admin: (r'^admin/', include(admin.site.urls)), )
The final step in configuring Django is to have Django auto-build your database to match all the default models that come with Django (users, groups, etc.). Django provides a management script that makes this exceedingly easly.
cd /var/www/mydjango/django_projects/mydjango/ ./manage.py syncdb
The final step is to configure Apache. As I mentioned previously, I wanted everything in a VirtualHost so as not to disturb the other web applications I have running on my test machine. To do this, I created a new site descriptor as /etc/apache2/sites-available/mydjango.mydomain.home. Some key setup notes to be aware of are below. Everything else is pretty standard for an Apache vhost.
- The <location “/”> element is used to set python and specifically Django as the handler for all requests. Note that I’m adding the location of my site to the PythonPath and I’m setting the path to my settings file as part of the environment.
- The alias and additional <location> elements are used to overrie Django and allow Apache to server up the files directly. The aliases are set up point to the directories created earlier for the Django site
My final configuration file is shown below.
<VirtualHost *> RewriteEngine On ServerAdmin TomS@hackrunner.com ServerName mydjango.mydomain.home #set up Django as the default handler for the site <location "/"> SetHandler python-program PythonHandler django.core.handlers.modpython SetEnv DJANGO_SETTINGS_MODULE mydjango.settings PythonPath "['/var/www/mydjango/django_projects'] + sys.path" </location> Alias /media /var/www/mydjango/media <location "/media"> SetHandler None </location> Alias /admin_media /var/www/mydjango/admin_media <location "/admin_media"> SetHandler None </location> <locationmatch ".(jpg|gif|png)"> SetHandler None </locationmatch> ErrorLog /var/log/apache2/mydjango.mydomain.home-error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/log/apache2/mydjango.mydomain.home-access.log combined </VirtualHost>
After that, I made sure that my domain name was correctly set up on my local DNS server (or you can use a local hosts file), then I enabled the site and reloaded Apache.
sudo a2ensite mydjango.mydomain.home sudo /etc/init.d/apache2 reload
I then navigated to http://mydjango.mydomain.home. I immediately got the 404 page you see below, which means that Django is working, I just haven’t set up any views yet.
As a secondary test, I also went to http://mydjango.mydomain.home which showed the admin login screen below.
And that pretty much wraps it up. Django is up and running and ready for development. I’ll be giving Django a test drive. If things go well, there will likely be some more blog posts on the topic soon.