Django wiki

I tried a little experiment today: see how fast I can build a minimal wiki using Django. Writing a quick wiki is a good way to show off Django, and a good learning exercise, so here's the code.

First off, a minimal settings.py file; our project is called "wiki" and the application is "wiki.pages":

DEBUG = True
TEMPLATE_DEBUG = DEBUG
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'wiki.sqlite'

ROOT_URLCONF = 'wiki.urls'

INSTALLED_APPS = (
    'wiki.pages',
)

urls.py only needs to direct all requests to the wikipage view:

from django.conf.urls.defaults import *

urlpatterns = patterns('',
    (r'^(?P<name>.*)$', 'wiki.pages.views.page'),
)

The model is also dead simple, just a name and some content for each page:

from django.db import models

class WikiPage(models.Model):
    name = models.CharField(max_length=128, primary_key=True)
    content = models.TextField()

views.py is where all the action happens. It needs to fetch pages (which may not exist), find CamelCase words and turn them into links, and also handle page modifications. I'm fetching the current page content before checking for page editing (form submission) because this makes for cleaner code.

import re
from django import forms
from django.shortcuts import render_to_response
from models import WikiPage

class WikiPageForm(forms.ModelForm):
    class Meta:
        model = WikiPage
    name = forms.CharField(widget=forms.HiddenInput)
    content = forms.CharField(widget=forms.Textarea({'rows': '8', 'cols': '60'}), label='')

def page(request, name):
    name = '/' + name
    
    try:
        wiki_page = WikiPage.objects.get(name=name)
        content = wiki_page.content
    except WikiPage.DoesNotExist:
        wiki_page = None
        content = 'This is a new page. It will be created when you click "save".'
    
    if request.method == 'POST':
        form = WikiPageForm(request.POST, instance=wiki_page)
        if form.is_valid():
            wiki_page = form.save()
            content = wiki_page.content
    else:
        form = WikiPageForm({'name': name, 'content': content}, instance=wiki_page)
    
    def make_link(m):
        return '<a href="/%s">%s</a>' % (m.group(1), m.group(1))
    
    return render_to_response('wikipage.html', {
        'name': name,
        'content': re.sub(r'([A-Z]\w+[A-Z]\w+)', make_link, content),
        'form': form
    })

Finally we need an HTML template. It's missing <html>, <head> and <body> tags but browsers don't mind :)

<h1></h1>
<pre></pre><hr>

<h2>Edit page ""</h2>
<form method="POST"><br><input type="submit"></form>

The original implementation took me just under 20 minutes (much of that was spent looking up some of Django's API). What I've published here is a bit more refined and elegant, but it does the same thing.

Created:
21 Nov 2008, 00:37
« previous
(Elections)
next »
(Nouvelle Vague concert)