HN Debrief

What I love about Django

  • Programming
  • Developer Tools
  • Startups
  • Open Source

The post is a love letter to Django as a mature web framework that has kept its core promises for years. It praises the usual strengths that made Django sticky in the first place: built-in admin, migrations, strong docs, sane defaults, and a framework that evolves carefully instead of forcing periodic rewrites. That landed with a lot of people who have old codebases still upgrading cleanly across major versions, which is a rare claim in web development.

If you run a startup or internal platform team, Django still looks like a strong default when you value speed, admin tooling, and low rewrite churn over architectural purity. The watchout is that large teams need explicit rules around query boundaries, data access, and async workloads, because Django will not enforce that discipline for you.

Discussion mood

Mostly positive and appreciative. People value Django's stability, admin, migrations, and ability to support long-lived products without forced rewrites. The frustration centers on the ORM, hidden query costs, and the fact that Django gives teams enough rope to create spaghetti if they do not enforce architectural boundaries.

Key insights

  1. 01

    Upgrade stability is a real competitive advantage

    Long-lived Django codebases keep moving forward without the routine major-version trauma that many web stacks normalized. People running ten- and twenty-year projects said clean upgrades are common enough to be boring, which is exactly what makes Django valuable for revenue-generating systems that cannot afford framework churn every few years.

    Treat framework stability as an operating cost decision, not just a developer preference. If your product has a long tail, Django's low rewrite pressure can beat trendier stacks even when they feel nicer on day one.

      Attribution:
    • JodieBenitez #1 #2
    • almost #1
  2. 02

    Django works well as a back office layer

    Several people described a split architecture where Django handles migrations, data modeling, and admin, while another stack serves the customer-facing API or performance-sensitive paths. In that setup Django becomes a database builder, inspector, and operations console rather than the whole application runtime, which preserves its strongest features without forcing every request through it.

    If your team likes Django's operational tooling but not its request path limits, do not frame this as all-or-nothing. You can keep Django for schema and admin while moving hot paths or external APIs to Rust, Go, or another service layer.

      Attribution:
    • dzonga #1
    • Klonoar #1 #2
    • tclancy #1
  3. 03

    Teams add service layers to contain the ORM

    People who stay happy with Django at larger scale often stop passing models everywhere. They put database access behind selectors or services, then pass dataclasses or Pydantic objects deeper into the system. That is not just style preference. It is a way to prevent query sprawl, keep business logic out of model managers, and make schema changes less explosive.

    If your Django codebase is growing, set a rule early about where queries are allowed. Add service or selector boundaries before model objects leak across the whole app and turn every refactor into a production risk.

      Attribution:
    • saaspirant #1
    • giancarlostoro #1
    • matsemann #1
  4. 04

    Signals are fine when kept tiny

    Signals got a more practical defense than their usual reputation suggests. They work best as narrow glue for decoupling apps, with the signal handler doing only the minimum work needed in the transaction and pushing everything heavier to Celery. The failure mode is not signals themselves. It is treating them like a hidden workflow engine.

    Use signals only for small, explicit side effects and document them like public interfaces. If a handler needs real business logic or slow work, move that logic into a task or service instead of hiding it behind model saves.

      Attribution:
    • phn #1 #2
    • tclancy #1
  5. 05

    Django is still sanding down ORM pain points

    Some of the ORM complaints were about specific defaults rather than the whole idea. People called out silent N+1 behavior, fetching every field by default including heavy text or blob columns, and save() rewriting entire rows unless update_fields is set. A commenter pointed to Django 6.1's upcoming field fetch modes as evidence that the project is still addressing these rough edges in core.

    Keep an eye on newer Django releases if ORM performance annoyances are part of your hesitation. Some pain points now have first-party fixes or better defaults than teams remember from older versions.

      Attribution:
    • infamia #1
    • lozenge #1
    • ranger_danger #1

Against the grain

  1. 01

    Modern deployment and async needs can outweigh Django's strengths

    A few people argued that Django feels awkward in a world built around CDN-hosted frontends, serverless backends, and heavy async workloads. The complaint was not that Django cannot work, but that it asks for a more traditional always-on server model and still pushes some teams toward Go or lighter frameworks when throughput or async coordination dominates the problem.

    If your product leans hard on async IO, edge deployment, or highly elastic infrastructure, test Django against those constraints before standardizing on it. Its long-term maintainability benefits do not erase runtime and deployment tradeoffs.

      Attribution:
    • whateverboat #1
    • daft_pink #1
    • fmind-dev #1
  2. 02

    FastAPI-style stacks feel cleaner for API-first work

    One commenter liked Django's ORM but said the framework makes simple things easy and complex things hard, with too much magic for the web layer. That points to a real split in Python land. Teams building mostly APIs may prefer FastAPI or Litestar for a more explicit request model while keeping Django out of the serving path entirely.

    Separate your data-layer choice from your web-layer choice. If your app is API-first, compare Django against lighter Python frameworks instead of assuming the ORM and the request stack have to come as a package.

      Attribution:
    • explorigin #1
    • dzonga #1

In plain english

Active Record
A software pattern where a model object represents a database row and also contains methods for querying and saving itself.
API
Application Programming Interface, a way for software to call another service or model programmatically.
async
Short for asynchronous programming, where a program can handle waiting on network or disk operations without blocking the whole process.
B2B
Business to business, meaning products or sales aimed at companies rather than individual consumers.
Celery
A Python task queue used to run background jobs outside the main web request.
CRUD
Create, read, update, and delete, shorthand for basic application features that store and manipulate data.
N+1
A performance problem where code fetches one list of records and then triggers one extra database query per record, causing many unnecessary queries.
ORM
Object-Relational Mapper, a library that lets developers work with database rows as language objects instead of writing raw SQL for every query.
prefetch_related
A Django ORM feature that loads related records in separate bulk queries and attaches them to objects to reduce repeated database access.
Pydantic
A Python library for defining structured data objects with validation and type hints.
raw SQL
Hand-written SQL passed directly to the database instead of being generated through an ORM.
select_related
A Django ORM feature that loads related database records in the same query to avoid extra lookups later.
SQLAlchemy
A popular Python database toolkit and ORM that many teams use as an alternative to Django's built-in ORM.

Reference links

Django architecture and workflow patterns

Alternative Django tooling

  • django-fquery
    Suggested as an abstraction layer over Django so plain Python dataclasses can be mapped onto Django primitives.
  • django-bolt
    Mentioned twice as a way to change Django's architecture and improve request handling performance via Rust.
  • nanodjango
    Recommended as a strong option for single-file Django apps.

Django docs and upcoming features

ORM alternatives and comparisons

Historical and adjacent framework references