Skip to main content

The history of a Django application

·7 mins

I want to expand on the history that did not fit into the presentation at DjangoCon.

Last year, I got the opportunity to give a presentation at two of the biggest Django conferences. First at DjangoCon Europe in Edinburgh, Scotland and then at DjangoCon US in Durham, North Carolina.

The presentation was called “The evolution of Django application” and I prefer the video for DjangoCon US. Here are the slides.

I’ll use three geological eras, to characterize the evolution of what started as a couple of PHP functions without any framework to tell the history that did not fit into the presentation.

The Palaeozoic era: aether #

In 2001, I started a project called aether to redo Radio Helsinki’s Website with PHP and MySQL, in order to accommodate the increasing needs for displaying the current schedule1.

I used CVS on my computer and published the versions on an user homepage I had at mur.at. GitHub did not even exist at that time.

It was my first project with PHP and I was proud of its simplicity and some clever functions and some of the SQL queries it used.

That was until somebody used SQL injection to expose all the usernames and their passwords.

I remember hating PHP for the first time for letting me do what led to the SQL injections, the tutorials for misleading me to do it. And me for storing the passwords as plain text.

I updated the code to avoid SQL injections and started using md5-hashed passwords after that.

Some of the things that have survived from this time are the concept of a show, the “rhythm” of repetitions of a show, having the start and end time, first and last dates of this repetitions and the concept of a “note” that could be assigned to the date of a repetition to store additional information about a repetition.

Why all this?

Radio listeners usually want to know when I can listen to a show again.

There are simpler answers for this: “every Friday at 7 pm” and “every day at noon”, “on weekdays at 7 am”, but there are also other answers like “every first Monday of the month at 8 pm”.

It used modulo-arithmetics to describe these rhythms without having to create a record for every repetition2.

Day schedule for using aether
Day schedule for using aether

It definitely had a lot of imitations, but it stayed in use for more than ten years.

The Mesozoic era: pv #

In 2011, Johannes Raggam and I started a project to replace the PHP Website with a combination of Plone and Django.

I can’t recall what actually led us to this solution, specially since there were already some Django CMS solutions, but I think my lack of Web design skills and having Johannes in the team played a major role.

I was proud of the solution specially the Django application.

The way Plone integrated with Django also seemed cool.

Some of the things that survived from this time are the different models used for the categorization of the shows: the “broadcast format”, “language”, “music focus”, “show information” and “show topic”, but also the model of a"host" of a show.

Some of they have different names and are now many-to-many fields, but they are still there.

But the main improvement was the introduction of the “recurrence rules” that together with the “program slots” would generate “time slots” to fill the daily schedules and that the show notes were now attached to these timeslots.

The decision to use dateutil to generate these repetitions and to split the recurrence rules in two models with the RRule and the ProgramSlot was probably the best decision made very early in the development of pv.

And definitely with “more luck than understanding”.

The migration of all the historical going data back to around 2005 from the previous aether database was a breeze and I thought of it as a sign that at least parts of the schema were not just clever but right.

The Administration Interface #

The main limitation that came with this solution was that we had to split the administration in two interfaces.

We used Django’s admin interface to manage the whole programme, that is creating, updating and deleting the hosts, the shows, the program slots, the time slots and the notes.

Django administration interface for pv
Django administration interface for pv

The Django documentation used to discourage from doing this, but we allowed not only the programme managers but every host of a show to manage the notes for their own show(s) using the admin interface.

It worked and more than ten years later, it still works3.

HTML, CSS and JSON #

To render the programme pages4, Plone would get the pages from the Django “back-end” as plain HTML and integrate them into the Website using what was back then called Deliverance.

In Django we had list and detail views for hosts and shows, but also day and week schedules and “boxes” for the classification (broadcast format, language, music focus, show topic and information), the previous, current and next show and show recommendations.

With time, we added some things like abbreviations, icons, colors and buttons to the models used for the displaying the classification of the shows on the Website, and views to serve CSS files to be used by the Website to work around some limitations of Plone and the design of the site.

We fortunately removed these two years ago.

I was very proud of the week view that would generate plain HTML with the full programme, only using div elements, that with CSS would render a fully colored schedule, in Plone.

Fully colored week schedule using pv and Plone
Fully colored week schedule using pv and Plone

We eventually added some views that serve JSON files to represent the state of the programme to drive Radio Helsinki’s automation.

This led us to where we are now: steering is the “source of truth” for the programme.

The Cenozoic era: steering #

Between 2017 and 2019, Ingo Leindecker contributed very important parts of what is now steering.

Ingo made the application into a restful API to manage the programme and solved the main pain points that pv had: timeslot collision detection and conflict resolution.

Around 2020, I was contacted by Radio Helsinki about the pv project.

I was asked if I would be willing to re-license it as AGPLv3, to be used for the AURA, a joint project of some of the free radios in Austria, to replace their radio automation systems.

Two years ago, I was invited to join the project and be the leader of the development of what started as pv and was now called steering.

This is the current data model for steering, including the latest changes that are not yet part of the main branch.

Current data model of steering
Current data model of steering

Last year, I was asked to be the maintainer of tank, the import and playlist daemon of AURA, that is written in Go and was contributed by Christian and Radio Helsinki to the project.

I’ll write about tank in the future, once I’m confident enough to explain it.

The present and the future #

At the end of January 2023, we are aiming for our third alpha release within the coming weeks, with what I hope will be the next-to-last tweaks to steering’s data model.

There are goings to be some minor changes, or better additions, in the API, and some final clean-up.

We still have two more alpha releases planned before we can release the first beta before the end of the year 2024.

I want to pitch to our team to use Wagtail instead of WordPress for our Website once we deliver a stable version of AURA and deploy it at Radio Helsinki.

But this is something for another time, maybe for DjangoCon 2024.


  1. Back then the Website had no CMS or database behind it.

    It was made of HTML pages and the homepage had to be manually edited with the current show. ↩︎

  2. Today, I’m still amazed that it worked for so long. ↩︎

  3. It actually kind-of works.

    Whenever creating or updating a program slot generates conflicting timeslots, that cannot be saved into the database, the admin interface just returns an error without much information about what went wrong and how to solve it.

    Luckily, this has been solved in the new steering↩︎

  4. It turns out, the homepage and the show pages are the most dynamic pages of the Website.

    The homepage changes almost every hour through the day, the show pages change at least every week, when a new episode of the show is broadcasted. ↩︎