Python – Django ORM’s “related data” loading behavior

djangodjango-modelslinqlinq-to-sqlpython

In LINQ (I come from a C# background), you can manually load data for related tables via the Include("xxx") method

from a in ctx.MainTable.Include("SubTable")
select a;

In the above code, every instance of MainTable is loaded and all the data for MainTable.SubTable is also loaded. If "Include" is not called, every returned MainTable's SubTable property will return null.

Are there equivalent methods for the Django ORM? If not, what's the default Django behavior for situtions like the above?

Best Answer

See this:

http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4

You create a select_related query set to follow relationships and pre-fetch related rows.

Normally, you don't waste much time doing this until you know that the individual fetches done automagically by the ORM are too slow.

When you simply name a related object field:

x = MainTable.objects.get( id="some Object" )
y= x.subTable

The ORM will do the of the related subTable row. lazily.

You can't easily fetch an entire table into memory. QuerySets are "lazy" and don't fetch rows until there's no possible excuse. Consider this.

for m in MainTable.objects.all():
    y = m.subTable
    if y.someAttribute > 5: 
        break

Then you may not actually need all the objects in MainTable. The query set is ready to fetch them. It just doesn't actually fetch them all. That's why we don't generally do anything more than x.subTable and leave it to the ORM to fetch the row as needed.

Once in a while you can prove that it's too slow. Then you can do MainTable.objects.select_related()... and force navigation to rows in other tables.