Articles
2026
Decomposing hardcoded roles: rewriting access control in a Django app without breaking customers
How we replaced three hardcoded roles with 46 named permissions and customer-defined roles, and proved nothing changed before changing anything.
Migrating a production Django app from Elasticsearch to OpenSearch
How a one-line urllib3 security bump turned into migrating a Django app from elasticsearch-py to opensearch-py, and what we vendored to keep the API responses unchanged.
Almost done: the hidden tradeoffs of Playwright E2E testing in a fast-moving app
A week of investigating Playwright on a fast-moving UI ended with a recommendation to stop. Four hidden costs that make end-to-end tests cheap to start and expensive to keep.
How I added project-aware tab completion to Django's manage.py
Django's bundled bash completion only knows command names and flags. django-completion adds app labels and migration names by reading a JSON cache that is rebuilt after each manage.py command, so Tab never loads Django.
From Django library to AWS Cognito: my journey building enterprise SSO
How a multi-provider SSO requirement took me from rewriting a Django SSO library to an AWS Cognito setup where adding a new identity provider needs no server code changes.
How to set up SSO authentication in your app's admin panel
How to configure SSO account and notification settings in a Django admin panel backed by AWS Cognito, automate the setup through an admin API, and trigger user soft-deletes from Azure and Okta.
How to test SSO authentication with Cognito and OIDC providers
How to test SSO login and logout through AWS Cognito with an external OIDC provider, check that the user was created, and what a failed group validation looks like.
How to configure AWS Cognito for SSO: a step-by-step guide
How to set up AWS Cognito for multi-tenant SSO: an app client per customer, a custom groups attribute, external OIDC providers, and a managed login page.
Okta single sign-on (SSO) setup: a step-by-step guide
How to set up an Okta OIDC application for SSO: groups, role attributes, scopes, claims, access policies, event hooks for soft-deleting users, and optional MFA.
Azure single sign-on (SSO) setup: a step-by-step guide
How to register an app in Azure (Microsoft Entra ID) for OIDC SSO: scopes, group claims, API permissions, app roles, groups, user soft-deletion, and optional MFA.
2025
Django without the mess: repositories for data, services for rules
Why selectors are a trap for cleaning up fat Django models, and how repositories for data access plus services for business rules keep the layers apart.
Django REST Framework: when (and when not) to override serializers and viewsets, part 2
Part 2 covers ViewSets: when to override create versus perform_create, how update, partial_update, and perform_update fit together, and a cheat sheet for where each kind of logic goes.
Django REST Framework: when (and when not) to override serializers and viewsets, part 1
Part 1 covers serializers: which methods to override for validation, saving, and output formatting, and what logic does not belong in a serializer at all.
Why Django REST Framework doesn't show your custom validation error messages (and what to do about it)
DRF validates at the serializer level and skips model full_clean(), so custom messages on model constraints never reach the API response. Three ways to work around it.
Boost your Django Docker images by using uv package and project manager
A multi-stage Dockerfile for Django that installs dependencies with uv, uses cache mounts for faster rebuilds, and works around a .venv permission issue. In my project the build went from 34.6s to 15.8s.