Q objects, F objects, annotate, and aggregate: the four tools that let you stop dropping to raw SQL, and the one distinction everyone gets wrong.
Most Django developers use maybe 20% of the ORM. They know .filter() , .get() , .all() , .order_by() . The moment a query needs anything more interesting (an OR condition, comparing two columns, counting related rows, a GROUP BY), they either write a clumsy loop in Python or drop to raw SQL, convinced the ORM "can't do that."
It almost always can. The ORM has four tools that cover the vast majority of "complex" queries, and they're not advanced or obscure. They're just under-taught.
This article walks all four in plain English:
Q objects (OR/NOT logic)
F objects (comparing fields to each other)
annotate (per-row computed columns)
aggregate (whole-table summaries)
And it clears up the single most confused point in the entire ORM: the difference between annotate and aggregate .β¦