Django password reset flow with email

Django provides built-in password reset views. I customize templates to match site design. The flow sends a secure token via email that expires after a timeout. I configure email backend and PASSWORD_RESET_TIMEOUT in settings. For better UX, I customi

Time Zone Safe Scheduling

Scheduling bugs are often time zone bugs. Persist times in UTC, accept user input in their zone, and convert explicitly. Keep conversions close to the boundary (forms/controllers).

Row-level locking with SELECT ... FOR UPDATE in a transaction

Optimistic locking is great for most user edits, but sometimes you need strict serialization—like decrementing inventory or consuming a one-time token. In those cases I use SELECT ... FOR UPDATE inside a transaction. The lock is scoped to the transact

Turbo Stream flash messages without custom JS

Instead of sprinkling custom JS for notifications, I treat flash as UI state and render it via Turbo Streams. When a create/update succeeds, the controller responds to format.turbo_stream and the template uses turbo_stream.replace to swap the flash co

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

Strong parameters for mass assignment protection

Strong parameters prevent mass assignment vulnerabilities by explicitly whitelisting which attributes can be set via user input. Without this protection, attackers could modify sensitive fields like admin or account_balance by including them in reques

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

errors.Join for cleanup (surface multiple close failures)

Cleanup paths are easy to under-test, and it’s common to ignore close errors because you only have one return value. With Go 1.20+, errors.Join gives you a clean way to accumulate multiple cleanup errors and return them as a single error value. This i