Django celery task for async email sending

I use Celery for any operation that might be slow or fail intermittently, like sending emails. By decorating with @shared_task, I make tasks reusable across different apps. I set bind=True to access task instance (useful for retries), and configure re

Django context processors for global template variables

Context processors add variables to every template context automatically. I create a function that takes request and returns a dict. This is perfect for site-wide settings like site name, current year, or user preferences. I add my processor to TEMPLA

Structured Exceptions with Context

In production, stack traces without context are slow to debug. Raise custom exceptions that include IDs and safe metadata, and log them as JSON. This is the difference between “we think” and “we know”.

Stimulus: intersection observer for “mark as read”

For notifications/messages, it’s nice to mark items read when they actually enter the viewport. IntersectionObserver + Stimulus keeps it lightweight, and Turbo streams can update badges in real time.

Strict Loading to Catch N+1 in Development

I enable strict loading when I want N+1 bugs to fail loudly during development instead of quietly shipping to production. In Enable strict_loading on associations, I mark the relationships that routinely get iterated (has_many :line_items and belongs_

Password reset tokens: hash + expiry

Reset flows are a common place to accidentally store secrets in the database. I generate a random token, email it to the user, and store only a hash in the DB alongside an expiry timestamp. When the user redeems the token, I hash what they provide and

Time-ago formatting with Stimulus (no heavy date libs)

For small UX touches like “3 minutes ago”, I don’t want to pull in a giant date library. A Stimulus controller can use Intl.RelativeTimeFormat plus a lightweight difference calculation. The server renders the ISO timestamp (via time_tag), and the cont

Repository pattern for DB access (small, pragmatic)

Not every codebase needs full-blown DDD, but I still want a clean seam between business logic and SQL. A tiny repository module per aggregate gives me that seam, and it makes testing easier because I can stub repository methods rather than mocking the

Content Security Policy headers (defense-in-depth)

XSS is still the most common ‘we didn’t think about it’ vulnerability in web apps. A Content-Security-Policy doesn’t replace sanitization, but it dramatically reduces blast radius when something slips through. I start from a strict baseline (no inline

API input coercion for query params (Zod preprocess)

Query params arrive as strings, and ad-hoc parsing logic tends to drift across endpoints. I use Zod preprocessors to coerce values like page size and booleans, then validate the result. This keeps the handler readable and makes parsing rules shareable

Model broadcasts: prepend on create, replace on update

When updates can happen from multiple places, model-level broadcasts keep the UI consistent across tabs without sprinkling stream logic in controllers. Use after-commit hooks so broadcasts only occur once the write is durable.

Django form validation with clean methods

I use clean_<fieldname>() to validate individual fields and clean() to validate field combinations. Raising ValidationError shows the message to the user near the appropriate field. For cross-field validation (like 'end date must be after start