Mar 20, 2026

Next steps...

  • ty was fast but not very useful, wouldn't surprise me if this gets killed off first.
  • ruff was a fast and convenient wrapper to a bunch of tools I was already using, should be easy to revert back to using Black, flake8, etc.
  • uv will be more difficult, especially with the option to download/run a specific version of Python, but should be able to revert back to using pip-tools and pipx.


Mar 4, 2026

You can have a read through the Bootstrap v6 alpha docs here

The new colour palette looks good and uses the modern OKLCH colour space. There are also a bunch of new form components, and some other goodies. Looking forward to giving it a go.




Nov 4, 2025

The next phase in our dystopian future... AISO: AI summarisation optimisation

Meetings—humanity’s most fundamental collaborative ritual—are being silently reengineered by those who understand the algorithm’s preferences. The articulate are gaining an invisible advantage over the wise. Adversarial thinking is becoming routine, embedded in the most ordinary workplace rituals, and, as AI becomes embedded in organizational life, strategic interactions with AI notetakers and summarizers may soon be a necessary executive skill for navigating corporate culture.

https://www.schneier.com/blog/archives/2025/11/ai-summarization-optimization.html



Migrate SQLite to PostgreSQL with pgloader

I recently needed to change one of my Django apps from using SQLite to PostgreSQL. I thought it was going to be challenging to move the data from the SQLite database file to my PostgreSQL server, but it couldn't have been easier! ✨

After installing pgloader with a simple apt install pgloader command, I ran the following command to move the data:

  • pgloader sqlite:///path/to/my/db.sqlite3 postgresql://username:password@host:port/db_name

Done! 🎉

There's a lot more that pgloader can do, and it's worth reading the docs, but my simple SQLite migration worked the first time and without drama. 🥳


I Love Justfiles

About a year ago, I switched my Django development workflow to include justfiles which are "recipes" of tasks to be used with the just task runner.

Since then, I find myself dropping little justfiles all over the place. Here's one I created for an Ansible repository:

# Show all available commands
default:
    @just --list

# Run playbook in check mode (dry-run)
check ENV="dev" PLAYBOOK="site":
    ansible-playbook --diff -i ./inventory/{{ENV}}/hosts.yml --check playbooks/{{PLAYBOOK}}.yml

# Run the main site playbook
run ENV="dev" PLAYBOOK="site":
    ansible-playbook --diff -i ./inventory/{{ENV}}/hosts.yml playbooks/{{PLAYBOOK}}.yml

Super simple 🚀, and it lets me run a bunch of Ansible playbooks like this:

> just check
ansible-playbook --diff -i ./inventory/dev/hosts.yml --check playbooks/site.yml
just check prod
ansible-playbook --diff -i ./inventory/prod/hosts.yml --check playbooks/site.yml
just run prod common
ansible-playbook --diff -i ./inventory/prod/hosts.yml playbooks/common.yml

Sometimes I'll drop one in the root of a remote server with a bunch of common tasks like installing updates, running various maintenance tasks, or monitoring the system. I used to do this with Bash aliases, but I prefer the just syntax, and it feels easier to copy the files around.

😍


Gave up on Datastar

I tried hard to like Datastar—I read docs and articles, watched many YouTube tutorials and interviews with the developers—but I'm giving up. There are some great demos around, but for just swapping DOM elements, HTMX (or Alpine AJAX) are easier to work with.

Also, Datastar has moved features into a "Pro" version that costs US$299! So if you want to update the URL after loading/swapping an element, that will cost you US$299. And from what I can tell (I can't test it), this won't update the browser's history, so the back button gets broken.

Both HTMX and Alpine AJAX can do this. I'm using Alpine AJAX for this in a new project, and it allows you to dynamically load content while updating the URL and the browser's history. Which means you can bookmark or share or refresh the page and use Django's logic to return the full content.


Oct 15, 2025

Trying hard to wrap my head around what Datastar is and isn't. The docs try to get you to use server-sent events, but at the same time it looks like you don't need to - you can use it in the same way you use HTMX with no backend changes.

The server-sent events look interesting, but Django has warnings against using them, especially with WSGI, but also with ASGI. So perhaps Django isn't a good fit for this?


Oct 7, 2025

A little reminder to myself: always check that the test suite is passing before making significant changes to a project!

Just wasted a couple of hours troubleshooting some changes I had made, only to roll them back and find that the tests weren't even working before I started. 🤦‍♂️





DJ Checkup Updates

I finally❗ got around to rewriting the DJ Checkup backend to make it easier to manage and update the security checks. In case you've never heard of it, DJ Checkup is a security scanner for Django sites. It looks for common security issues with Django sites, like DEBUG mode being left enabled in production, open admin site, etc.

The TL;DR is that I moved the core checking logic and check definitions into a package called djcheckup, and now djcheckup.com uses this package to perform the checks, which has massively simplified the site and should enable me to be more proactive with updates.

Read more...


Sep 28, 2025

OK - so the microblog integration works well, but no Markdown. Either leave the Markdown in the content or just don't use any Markdown.