> This is my biggest complaint about Django's ORM -- lazy fetching of foreign keys is great in a management shell but rarely desirable in production, and it results in inexperienced developers doing database queries in loops all the time.
I may be misunderstanding you, but isn't this what select_related and prefetch_related exist for?
Those are how you optimize it, but first you have to recognize the need. The easiest way to make this visible is to increase logging or install Django-debug-toolbar, so people can see when the query count jumps, but the best way to prevent regressions is to use something like the testing framework’s assertNumQueries() method to prevent regressions:
I’ve used that with a fuzzy number class which will say it’s __eq__ to any number below a specified max so you can say e.g. my homepage should take less than 10 queries and not have to touch it for minor changes while catching when someone implements a new feature in a way which breaks your select_related usage.
I may be misunderstanding you, but isn't this what select_related and prefetch_related exist for?