#28822: Add DBCalculatedField to model to annotate models automatically -------------------------------------+------------------------------------- Reporter: Ilya | Owner: nobody Type: New feature | Status: new Component: Database layer | Version: master (models, ORM) | Severity: Normal | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- Changes (by Matthijs Kooijman):
* cc: Matthijs Kooijman (added) Comment: The idea in this issue has been bouncing around in my head as well for a while. I'm not entirely sure if *all* annotations should *always* be enabled, as suggested here, but I do see great merit in having annotations defined declaratively outside of a specific queryset instance. Because: - These annotations can be enabled using an automatic mechanism on a queryset (e.g. `qs.add_annotation('foo')`). - These annotations can be automatically enabled by using them in a filter, another annotation, etc., e.g. `qs.filter(foo__gt=1)` would load the `foo` annotation automatically, instead of having to do `qs.add_foo().filter(foo__gt=1)`. This is especially powerful when used in cross-relation lookups, where it is (AFAIK) not normally possible to add annotations on a related model. - These annotations can also be explicitly referenced and resolved to their query expression, for use as part of other expressions, queries, etc. I'm not entirely sure how this could be used yet, but I have the suspicion that making annotations named objects (outside of model instances) would allow for more reuse and composition. I originally also saw great merit in being able to calculate annotations in Python if they were not calculated during the query already (since this, in some cases, can remove the need to decide which annotations are needed beforehand). However, as extensively debated in the thread linked above this would have problems wrt performance (e.g. having to do subqueries or joins in Python) and correctness (subtle differences in database and Python handling of calculations), so I'm not so sure whether this would be feasible (but also less needed, if managing annotations is easier). In the mailing list thread above, SQLAlchemy's "[Hybrid Attributes](https://docs.sqlalchemy.org/en/13/orm/extensions/hybrid.html)" were also mentioned, which fulfill a similar use. They are actually quite interesting, but also quite different from how Django does things. Hybrid attributes are like property getter methods, which work (I think) as normal python code on an instance, but can also be accessed on the class to return an ORM query expression equivalent with the python code in the method, to be used in e.g. queries. It looks like they do some kind of DSL-like evaluation, or maybe even AST-analysis of the python code for this conversion, pretty nifty. The local-vs-db problem seems to be handled by defaulting to an automatic conversion, but allow overriding the db expression for more complicated cases. They even allow writing such hybrid attributes (with some additional declarations), which is also nice. Regardless, this does not seem like something that is easily implemented for Django, or fits the current ORM structure well, so probably not so useful here and now. -- Ticket URL: <https://code.djangoproject.com/ticket/28822#comment:6> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/071.d7605caea19ba268b8659085dde9abd6%40djangoproject.com.