Re:Lessons learned defying Joel Spolsky with Django
by subleq on Saturday April 27, 2013 @04:32PM
(#5618951)
You are mistaking about filtering an annotation.
> Model.objects.annotate(Count('foos')).filter(foos__lt=10)
The only reason this doesn't work is because the property annotate creates isn't called `foos` by default. You just need to do this: Model.objects.annotate(foos=Count('foos')).filter(foos__lt=10)
and Django now knows to add a `HAVING COUNT(foos) < 10` clause.
Consider how people often write update code on Django:
This sucks a lot. It's doing two queries, and you have concurrency issues. This would be optimal, since it's atomic: But in this case, it's not instantiating any object nor triggering any signals, so what's the point of the ORM after all? We might as well just use a sane DB API.Here's another place where Django's ORM fails:
This won't work. Django will complain 'foos' is not a field on the model - even though 'foos' is a column in the result set, and it's perfect valid to SELECT on it. I reported this as a bug, but because the ORM works with model definitions and the result set can contain any column, what the ORM is really supposed to do or not is murky, so it's WONTFIX. This is one instance where data doesn't map to an object and the ORM concept crumbles.There are many other pain points with ORMs, and Django's in particular, but these are the highlights for me. For an elegant querying API, in my opinion, check out RethinkDB. It doesn't depend on schemas (therefore, ORMs) and it supports map/reduce semantics, which solves 100% of what you need to do with data.