Some more things about Django I've been enjoying
Skip to main content
Hello! I’m on a funny journey right now where I’m trying to learn how to make<br>websites in a sort of 2010 style, where I have an SQL database and render some<br>HTML on the backend.
It’s kind of an interesting journey because it doesn’t necessarily feel “easy”<br>to me to make websites in this way: I never learned how to do it in the 2000s or<br>2010s, and there’s a lot I need to learn.
So here are some Django features that make building this kind of site feel<br>more realistic than when I was trying and failing to use Go’s standard library<br>or Flask. And I’ll talk about a couple of issues with Django I’ve run into.
why learn to make websites like it’s 2010?
Previously the toolkit I felt confident with for making websites was:
static site generators (like for this blog)
static sites that do some fun stuff with Javascript (like this sql playground)
simple Vue.js single page apps with either a Lambda as a backend or a Go backend (like mess with dns)
I really liked this frontend-heavy approach for these super simple applications<br>but when I started thinking about making something with a lot of different pages<br>(instead of literally just one page), I didn’t feel so excited about the options<br>I saw that involved a lot of frontend code. So I figured I’d try the backend.
Writing a backend-focused site that uses as little JS as possible feels<br>the same to me in a way as writing a single-page JS website that does as little<br>on the backend as possible, even though they might seem like opposites. In both<br>cases I’m just trying to keep as much of the logic as possible in one place.
Now for some thoughts about Django!
I’m enjoying query builders
I learned that I can define a “query set” class in Django with a bunch of<br>methods with different WHERE statements I might want to use while constructing<br>a query:
class EventQuerySet(SearchableQuerySetMixin, models.QuerySet):<br>def approved(self):<br>return self.filter(approved_at__isnull=False)
def future(self):<br>today = timezone.localdate()<br>return self.filter(end__gt=self._midnight(today))
def with_tags(self, tags):<br>if tags:<br>return self.filter(tags__name__in=tags).distinct()<br>return self
Then if I want to filter events in my view code, I can write something like<br>this:
Events.objects.approved()<br>.for_tab(tab)<br>.with_festivals(tab_params.festival_slugs)<br>.is_free(tab_params.free)<br>.is_outdoors(tab_params.outdoors)
It feels super readable and nice to use, and it makes me want to look into other<br>query builder libraries in the future. In the past I thought “I know SQL, who<br>needs a query builder?”, but this kind of structure does make it really nice<br>to read.
I found an example of someone who wrote their own small query builder in Python<br>that I want to read later to think about whether I would enjoy using a more<br>minimal version of this.
the template filters are awesome
There are a bunch of little quality of life<br>filters available in Django templates that are super useful for generating HTML. The ones I’ve used so far are:
translating plain text URLs into links, or line breaks into ({{ event.description|urlize|linebreaksbr }} )
formatting dates ({{ row.date|date:"M j" }})
json_script, which takes a Python dictionary and automatically converts it to JSON and inserts it into the HTML as a tag in a safe way
These are all small things individually but I feel like it makes a big difference somehow to just have them available.
querystring is cool
I think my favourite template filter is querystring: in this site sometimes<br>we use filters like ?date=2026-06-01 to decide what’s displayed. querystring<br>that will make a link to the same query string with one change, like this to<br>link to the previous date:
Or to remove the outdoors parameter:
automatic database migrations are still great
I still really love Django’s automatic database system. It’s amazing to be<br>able to just edit a model to add a new field or whatever, and then Django<br>automatically generates the migration.
So far we have done 19 database migrations and I think there will probably be<br>more! It makes a huge difference for me to be able to just easily change the<br>database as my understanding of the problem changes.
I do not want to organize my code with inheritance
Django’s documentation sometimes offers the option of using class-based views<br>and inheritance to organize the code in your views. For example I have four<br>views that share a lot of code, and I could use inheritance to manage that by<br>defining some kind of parent class and then having my other views inherit from<br>it.
I tried it out and I did not enjoy the experience of using inheritance to<br>share code between views. I switched to using functions instead, sort of how<br>this post advocates, and that was a lot more straightforward.<br>I’ve never had a good experience...