Advent 2021: Django
This blog is part of the 24 posts long series "Advent 2021":
- Advent 2021: Intro (December 01, 2021)
- Advent 2021: C++ (December 02, 2021)
- Advent 2021: C# (December 03, 2021)
- Advent 2021: Python (December 04, 2021)
- Advent 2021: Go (December 05, 2021)
- Advent 2021: TypeScript (December 06, 2021)
- Advent 2021: CMake (December 07, 2021)
- Advent 2021: Django (December 08, 2021)
- Advent 2021: Angular (December 09, 2021)
- Advent 2021: Flask (December 10, 2021)
- Advent 2021: gRPC (December 11, 2021)
- Advent 2021: GraphQL (December 12, 2021)
- Advent 2021: XML & JSON (December 13, 2021)
- Advent 2021: Matplotlib, Pandas & Numpy (December 14, 2021)
- Advent 2021: Linux (December 15, 2021)
- Advent 2021: Ansible (December 16, 2021)
- Advent 2021: SQLite (December 17, 2021)
- Advent 2021: Catch2 (December 18, 2021)
- Advent 2021: Zstandard (December 19, 2021)
- Advent 2021: ZFS (December 20, 2021)
- Advent 2021: Thunderbird (December 21, 2021)
- Advent 2021: Visual Studio Code (December 22, 2021)
- Advent 2021: Blender (December 23, 2021)
- Advent 2021: Open source (December 24, 2021)
If you’ve visited my GPU DB, then you’ve already seen one of the projects I wrote using Django – my goto framework for serious web projects. I’ve been doing web development for many years now, originally with PHP 3 and 4, and then later with Python. In recent years, it was usually Python with Django when I knew that I had a bigger project to work on.
Why Django? For me, there are three key features that make Django great:
- It’s got a declarative object model with ORM capabilities
- It’s got a full template system built in
- It has a large ecosystem
The declarative object model is really the marquee feature for Django. Everything else in Django falls out of it, with the premiere feature being the ORM. The ORM is incredibly seamless: You can link objects together, query deep data structures, all using very simple markup. The template system is also tightly integrated and powerful enough that there is little reason to use something else. What I really like about the ORM is that it’s simple for simple tasks, but advanced uses are fully supported and don’t look awkward. For example, the GPU DB links cards to display connectors, and each card can have multiple connectors. This means you need a relation table to link them together with some extra data, and that is fully supported and looks like this:
class CardDisplayConnector(models.Model):
"""Map from card to display connector.
A card can have an arbitrary amount of various display
connectors, which is modelled by this class.
"""
connector = models.ForeignKey(
DisplayConnector,
on_delete=models.CASCADE)
card = models.ForeignKey(
Card,
on_delete=models.CASCADE, db_index=True)
count = models.IntegerField (default=1)
def __str__(self):
return '{}x {}'.format (self.count, self.connector)
class Card(models.Model):
...
displayConnectors = models.ManyToManyField(
DisplayConnector,
through='CardDisplayConnector')
...
That’s all there is to it, and it immediately shows up in the auto-generated administration, it creates a JOIN
when querying, and it’s easy to access and iterate over. Did I mention the auto-generated administration? That’s another great use of the extensive declarative model.
Finally, Django comes with a very large ecosystem. You want to expose your data using GraphQL? There’s a bridge for that, which reduces the amount of boilerplate a lot by utilizing the declarative model. Same for REST, caching, JWT – if it’s a remotely popular web technology, there’ll be a middleware for Django. If you always wanted to write a bigger web application but you didn’t know where to start, Django is just what you’ve been waiting for.