#20625: Custom Chainable QuerySets -------------------------------------+------------------------------------- Reporter: danols | Owner: danols Type: New feature | Status: assigned Component: Database layer | Version: master (models, ORM) | Resolution: Severity: Normal | Triage Stage: Accepted Keywords: QuerySet, | Needs documentation: 0 models.Manager, chainable | Patch needs improvement: 0 Has patch: 1 | UI/UX: 0 Needs tests: 0 | Easy pickings: 0 | -------------------------------------+-------------------------------------
Comment (by akaariai): I believe one problem with the proposed way is that chainable manager methods are lost when the QuerySet switches its class. The switching happens as side effect of certain calls (for example .values(), .values_list()). Also, creating dynamic classes as done in the patch is likely somewhat expensive, and will also likely break pickling (as the dynamic class can't be found from module level). Both of the latter problems are solvable, first one by caching the dynamic class, second one by altering QuerySet.reduce(). Other solutions to this problem are to make Manager itself a QuerySet (or subclass of it). I tried this some time ago and it was evident this path has a lot of problems ahead. Yet another solution is to call the chainable manager methods from the manager, but explicitly pass the queryset into the method, something like {{{ class MyManager: @chainable def published(self, chain_to, other_params...): return chain_to.filter(...) }}} with some meta-magic (or just plain old-style wrapper function) the chain_to could be automatically created as get_queryset() if called from manager, but if called from qs, then chained would be the qs instance. However it will be a bit confusing to call this method with objects.published(datetime.now())... Alternative is to not magically provide the chain_to qs when called from manager - instead the user should create the chain_to if it is None. A big +1 to the idea, but there needs to be a bit more discussion about what way to solve this. My opinion is that if it is possible to get rid of the Manager class completely, or make it QuerySet subclass, that would be optimal path. Unfortunately this seems hard to do. -- Ticket URL: <https://code.djangoproject.com/ticket/20625#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 post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/064.72a52fd5d103178751e8a3651b86b91d%40djangoproject.com. For more options, visit https://groups.google.com/groups/opt_out.