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.
