Hi Robert, On Wed, 10 Jul 2019 12:13:08 -0700 (PDT) Robert Schindler wrote:
> The traditional approach would be to implement methods for filtering > the queryset on both the managers for Subscription and User and thus > duplicating logic, or use sub-queries like so: > > User.objects.filter(subscriptions__in=Subscription.objects.active()) > > which is clearly not wanted because of performance. > Not so clearly. Querysets are lazy, so the above actually only performs one database roundtrip, and whether a join is more or less performant than an equivalent query-with-a-sub-query can depend on many details -- mostly details of the database engine implementations. If database engines were ideal, equivalent queries would have equivalent performance. More generally: The idea does seem interesting, but note that the prefix() method doesn't need to be a member of the Q class -- it seems to be just as easy to write an external function to do the same thing: def add_prefix(q_obj, prefix): """Recursively copies the Q object, prefixing all lookup keys. The prefix and the existing filter key are delimited by the lookup separator __. Use this feature to delegate existing query constraints to a related field. """ return Q( *( add_prefix(child, prefix) if isinstance(child, Q) else (prefix + LOOKUP_SEP + child[0], child[1]) for child in q_obj.children ), _connector=q_obj.connector, _negated=q_obj.negated, ) So, this can be added as a utility function to your project, or even published in a package on PyPI, without being in Django. Given this, the question is no longer just "is this useful", but rather "does this promote use-patterns we wish to encourage". On the ticket, Mariusz gave an example of a possible use-case we'd actually want to discourage. Here on the list, better use-cases were shown. One use case you didn't bring up is using a Q object with prefix as a "template" -- consider querying for the "first Tuesday of the month"; if there's a date field `d`, it would need to be something like ...filter(d__week_day=3, d__day__lte=7) But with a prefix, we could say something like def is_first_tuesday(field) return Q(week_day=3, day__lte=7).prefix(field) and then use it in ... filter(is_first_tuesday('d'),...) Which, at a very first glance, looks like an excellent use-case. Except that Django already has a way to support this, using custom lookups, which blend better into the QuerySet API -- and so, have technical advantages beyond the fact that they already exist and "There should be one obvious way to do it". So, I, at least, remain unconvinced that overall, this is an improvement to Django's API. Shai -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at https://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/20190711195702.71eb809b.shai%40platonix.com. For more options, visit https://groups.google.com/d/optout.