I seriously don't get why Django ORM is using the Active Record pattern. This is such a stupid footgun that trivially causes horrible performance and BEGS you to cause n+1 problems.
Never in my life did I have a problem with lazy loading causing unbearable performance until I joined a Python Django team. I really tried to find sympathy for the "dynamically typed" folks (please spare me saying Python is technically statically typed), but coming from writing apps and backends in Java, Swift, C#, Objective-C and PHP, Python with Django was the worst experience bar none.
I worked on the project for 10 months, could at least refactor the project to something semi-sane where obvious mistakes (which would not be possible in other languages) could not happen. Then along comes a "good Python dev" and threw it all out of the window and start doing SQL queries all over the place (typically 3-6 lines long), remove the domain objects and cause the same problems I started with to begin with. But his approach was saying that the other developers were "not good enough".
Yeah, have fun with schema changes going forward. Good riddance.
> BEGS you to cause n+1 problems
select_related, prefetch_related. n+1 problems be gone.
What would you have used instead?
Yes, if you attempt to use Django like you'd use your typical Java, Swift, C#, or Objective-C framework, you're not going to have a good time.
I've seen the horrors Java devs start doing on a Python project when trying to "fix" things, where by "fix" they mean use patterns they had to in previous gigs.
It's a different world.