Flirting with Django – part 1

Right now I’ve got a bit of time on my hands and I am slowly catching up with bits and pieces that I have been meaning to do for years. I have also decided to broaden my horizons and learn some Python and Java.

Why Python and Java? Well its simple really; I think Java would be really useful (in this part of the world), both career wise and in terms of being a better programmer; Python? – well my best friend raves about it all the time, its a bit different and Django seems so damn sexy (so far I am loving it).

Over the last couple of years I have dabbled with Django, run through the tutorials etc. but never quite had enough time to get to grips with it and Python at the same time. This time I have a specific project in mind and have decided to stick with it until I have something live and kicking on a web server out there in the big wide world.

(Un)fortunately I just blew my book budget on a pair of Java books – Sams Teach Yourself Java 6 in 21 Days (which is a superb book and I would recommend it to anyone learning Java) and Beginning JSP, JSF & Tomcat Web Development: From Novice to Professional (Beginning from Novice to Professional) (IMHO a bit mixed some of it is great, but chapters on HTML and Javascript are just filler), so in the absence of paper I have had to resort to the (excellent) online versions Django Book and Dive into Python. (Personally I’d take a real book over a screen any day – you can lie in sunshine in a hammock with your laptop and a beer, but you can’t see the screen and if you spill the beer it could be an expensive mistake)

My Setup

I’m developing on my laptop which runs Windows XP Professional. I already have an XAMPP webserver running on my laptop. I also have a copy of the Microsoft Power Toy – Open Command Window here, that lets you open a command prompt in any directory. I’m using Netbeans as an IDE, although I did start off with IDLE (the text editor that comes bundled with Python on Windows) but I got driven mad by all the windows.

The Django documentation runs through everything in detail and is a good place to start http://docs.djangoproject.com/en/dev/intro/install/#intro-install. Here is what I did:

  1. Download + Install Python
  2. Download + Install MySQL Python
  3. Download + Install Django + Set Paths in your windows environment variables
  4. Download + Install PIL (Python Imaging Library) so you can work with images

A few thoughts

Having worked mainly with ASP and PHP, the thing I have found most alien isn’t anything obvious like syntax differences it is the use of libraries . Of course they exist in PHP – think about things like PEAR – but for some reason they are not really a visible part of the language – PEAR is installed almost ubiquitously and in other cases people seem to just grab a library and dump directly into their application somewhere. Built in libraries (think GD or SPL) are just that built in and people don’t actually think about them. I think a lot of this is also a reflection of the nature of most PHP hosting which tends to be in cheap (and often shared) hosting environments where it is difficult to (if not impossible) to use non standard libraries, so people stick to the core.

To me therefore, it feels a little odd to have Django sitting in C:\Python25\Lib\site-packages and my application sitting E:\django\mysite

Getting started – create your project

Go to the directory you want to create your site in and then from the command prompt run:
django-admin.py startproject mysite.
This will create a project called mysite d within your current directory.

Create you app

Within a project you can have any number of applications – I’ve been thinking of an app as basically a plugin – a collection of related code. The idea is that you can take a number of apps and put them together inside a project and viola – a new site. An app might be a products database and shopping cart or it could be a blog or news system. But you can mix them all together and because of the unified Django admin interface they will all fit together perfectly. (The Django book explains it pretty clearly)

What’s the difference between a project and an app? An app is a Web application that does something — e.g., a weblog system, a database of public records or a simple poll app. A project is a collection of configuration and apps for a particular Web site. A project can contain multiple apps. An app can be in multiple projects.

To create an app Go to the directory you want to create your app in and then from the command prompt run:
django-admin.py startapp shop.
(This would create an app called shop within the mysite project)

Create your model

I usually have a pretty accurate database schema down in my notebook before I start any project and although you can import an existing schema and get Django to build the models, the preferred way seems to be to write your models and then get Django to create any necessary database tables based on your models. The latter method is certainly more useful from a learning point of view.

The basic workflow to create your models and synchronise them with the database is very simple indeed:

  1. Edit the models.py file within your app
  2. Generate the SQL for your shop app models with:
    manage.py sql shop.
  3. Create your database tables with:
    manage.py syncdb.

How easy is that?

The one thing to watch out for is that once a table has been created running syncdb will not update the database structure for that table – you either need to do this manually or use find a schema migration tool to use (something I haven’t tried yet)

Templates and Views

Once you’ve got a model or two in place, you probably want to do something with it. So you need to write a view. If you are coming from another MVC system, a Django View is basically equivalent to the Controller. I just followed the Django tutorial and played around from there. I didn’t make any earth shattering discoveries that weren’t in the book.

Django uses templateing engines to produce its output – commonly some HTML (but it could be anything, or even empty for AJAX) mixed in with placeholder tags and filters. When you view the page the place holders are replaced with data from the Model by way of the View. The template system seems to be deliberately sparse, but well thought out. If you need more functionality. you cna extend it by defining your own tags and filters or swap in an alternate template system.

You will need to specify the directory that your templates live in settings.py. e.g.

TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
'E:/django/mysite/templates'
)

If you just want to use Django admin as is you don’t have to do a thing, but if you want to customise it you can override and of the default admin templates just by creating new ones and placing them in a directory called admin inside your templates directory. Again very straight forward.

The one thing that I got stuck on for a short while is that Django doesn’t provide any default templates for your the public facing parts of your application. I don’t think it is that clear on this and I felt a while thinking I was doing something wrong before I realised I actually needed to just make them.

My simple base.html template looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="http://static.mysite.com/css/reset.css" type="text/css" />
<link rel="stylesheet" href="http://static.mysite.com/css/base.css" type="text/css" />
{% block meta %}{% endblock %}
</head>
<body>
<div id="container">
 
	<div id="header">
		{% block header %}{% endblock %}
	</div>
	<div id="content">
		{% block content %}{% endblock %}
		<div class="push"></div>
	</div>
	<div id="footer">
		{% block footer %}{% endblock %}
	</div>
</div>
</body>
</html>

The important thing here is are the placeholder tags e.g. {% block header %}{% endblock %}
In this case this is a placeholder for another template fragment called header so you can extend your templates ad infinitum.

Which brings me on to the only part of my Django experience so far that wasn’t great, it was the hair-pullingly frustrating experience of setting up to serve static files…

Serving Static Files

Django doesn’t like to serve static files (think css, js etc.). Even though I’m just developing on my laptop at the moment, I thought that it would be a good idea to try and mimic a production setup as closely as possible, and reading around the sensible thing to do was just serve all my static files from a sub domain. I’ve also got a copy of XAMPP running on my machine so I set up a subdomain in that to serve static files and experienced a total nightmare. I’m not quite sure why I had so much trouble, but I did, and I would imagine that this is the step where a lot of other people give up. Of course I got it working in the end (or else I probably wouldn’t be writing this, or at least not in a wow Django is so so cool kind of way…)

In the end I did get it working and it is possible that it is slightly weird. My actual Django project directory is within my XAMPP directory structure (because this is where I store all my code), but it is not served by the XAMPP Apache server (yet) – instead it is served using the python server: python manage.py runserver on http://127.0.0.1:8000/

So for the moment my static files are within the Django project (in the static directory) and can be accessed at: http://static.simbiotica.co.uk – in my settings.py has the following settings:


# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = './static/'

# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
#MEDIA_URL = 'http://static.simbiotica.co.uk'
MEDIA_URL = '/static/'

Update 19th July 2009

It turns out I was wrong! Thought it was all working, but when I started to dig deeper it wasn’t. Close though I think. For development have gone back to a more conventional setup in my latest post.

Django Files

The story so far…

So far my Django experience has been very positive and I can’t wait to get my first site done. I’ve successfully plugged in the Django Filebrowser into my admin system too. I think the thing I like most is wonderful terseness – you can achive so much writing so little, and from my currently extremely limited Python experience I’m really enjoying the language too.

3 Responses to “Flirting with Django – part 1”

  1. john

    Hi Daniel

    Glad you enjoyed it so far. To tell the truth I am going through alternate feelings of love and utter hate. Static files are still driving me up the wall. The are unnecessarily complex. Arggghh

    (been away just coming back to it all!)