> BEGS you to cause n+1 problems

select_related, prefetch_related. n+1 problems be gone.

You misunderstand. And that is exactly the problem.

We did do that and that's why our queries ended up being several lines long. But if you missed just one model? You openly walk a knife again.

It's a mess and it only gets longer and longer. I ended the project with having some proper aggregates, only for that to be thrown out of the window by the guy after me.

If you want to just prefetch everything throughout a project or just on a per-Queryset basis, all that is coming in the next release of Django.

https://docs.djangoproject.com/en/dev/releases/6.1/#model-fi...

That's the great thing about Django, it's been around so long and the quality bar is so high that eventually all the major rough edges get sanded away usually in a really well considered manner.

> our queries ended up being several lines long

Which is... perfectly normal for non-trivial needs.

> I ended the project with having some proper aggregates, only for that to be thrown out of the window by the guy after me.

How is that a Django problem though ? Sounds like a skill issue on your successor.

I get what you say, there's plenty of debates about ActiveRecord vs. AnythingElse, but in the end this one has its use and obviously has served many of us just fine. Different strokes... you know the drill.

I think there's an argument for throwing AttributeError instead of silently going to N+1 behaviour.

It still selects all fields by default. Very often I have to use defer() or only() to get rid of expensive columns like blob/text that are rarely used and greatly hurt performance when grabbing them.

Then it got to where I had to make a reflective function that I use like Model.objects.defer(*all_fields_except(Model, ['field1', 'field2'])), and then add another all_fields_except() for every select_related and prefetch_related.

Even save() by default re-writes every single field. You have to use save(update_fields=['field1']) instead.