Taming the beast that is the Django ORM – An introduction

Django’s object–relational mapper (ORM) is widely praised for its productivity, migrations, and tight integration with features like the admin UI and REST tooling, yet it also highlights enduring tensions around ORMs in general. Commenters contrast Django’s approach with alternatives such as Rails’ ActiveRecord, SQLAlchemy, Entity Framework, and raw SQL, debating trade-offs in complexity, performance (especially N+1 queries), portability, and how much developers should really abstract away from SQL. Several argue that modern aids like LLMs and type-safe query builders change the calculus, but there is broad agreement that understanding the underlying relational model and SQL remains essential for non-trivial applications.

Overall sentiment on Django ORM

  • Many consider Django’s ORM one of the better ORMs: simple things are easy, complex things are “figure‑out‑able,” and raw SQL is always an escape hatch.
  • Some who started with Rails’ ActiveRecord or SQLAlchemy find Django’s ORM less impressive or less flexible.
  • Several commenters note that Django has been “good enough” and stable for over a decade, with a strong backward-compatibility culture.

Comparisons to other ORMs and alternatives

  • Rails/ActiveRecord, SQLAlchemy, and Entity Framework are commonly cited as peers; some prefer Django, others strongly favor SQLAlchemy or ActiveRecord.
  • Other ORMs (Doctrine, some JS ORMs) are often described as clunky, magical, or hard to trust.
  • Query builders and typed SQL tools (HoneySQL, SQLAlchemy-as-builder, TypeScript SQL builders, jOOQ, Prisma’s TypedSQL, SQLKata) are praised as a middle ground: keep SQL semantics, add types and composability.

Raw SQL vs ORM

  • Many experienced developers increasingly default to raw SQL, even for simple queries, citing:
    • Easier mental model and debugging.
    • Full access to database features (CTEs, window functions, vendor-specific capabilities).
    • Easy copy-paste between tools.
  • Others argue ORMs are ideal for CRUD and “boring business apps,” with raw SQL reserved for complex reporting or performance hotspots.

Migrations, admin, and productivity

  • Django’s migrations are widely lauded as a standout feature for evolving schemas safely.
  • The auto-generated admin UI is seen by some as Django’s killer feature, especially for MVPs and internal tools; others find it clumsy, hard to extend, and unsuitable for non-technical users or complex workflows.
  • Several note that using Django’s ORM unlocks a broader ecosystem: forms, validation, REST APIs, permissions, and documentation patterns.

Performance, N+1, and lazy loading

  • Accidental N+1 queries are a major concern; tools like select_related/prefetch_related help but require vigilance.
  • Some want a global way to disable lazy loading or fail on it during development; third-party libraries exist, and there’s mention of ongoing core work.
  • There is disagreement on whether this is an ORM design flaw or a developer-competence issue.

LLMs and engineering practice

  • Some report success using LLMs to generate complex Django ORM queries and admin UIs, treating the ORM complexity as mostly “solved” by tooling.
  • Others strongly object, arguing developers must still understand and be able to justify each line of generated code; otherwise they’re “operators,” not engineers.

Broader critiques of ORMs

  • Classic objections appear: object–relational impedance mismatch, hidden SQL, debugging difficulty, performance unpredictability, and over-abstraction.
  • A contingent insists learning SQL directly is simpler and more portable than learning any ORM.
  • Another contingent counters that ORMs trade some purity and performance for large productivity gains, safer DB access in big teams, and faster iteration on changing business logic.