Django’s ORM is, in my opinion, the unsung gem of the framework. While not as full-featured as SQL Alchemy, what it lacks in power it more than makes up for in easy of use. For the subset of SQL that’s used in most web applications it’s very hard to beat. It’s a beautiful piece of API design, and I tip my hat to the people who designed and built it.
Lazy evaluation
If you haven’t spent much time with the ORM, two key features are lazy evaluation and chaining. Consider the following statement:
entries = Entry.objects.all()
Assuming you have created an Entry model of some sort, the above statement will create a Django QuerySet object representing all of the entries in the database. It will not result in the execution of any SQL—QuerySets are lazily evaluated, and are only executed at the last possible moment. The most common situation in which SQL will be executed is when the object is used for iteration: