> On 2 Jun 2020, at 19:42, Tim Graham <[email protected]> wrote: > > And here's some past discussion: > https://code.djangoproject.com/ticket/24141 - contains() method for QuerySets > (closed as needsinfo due to no mailing list discussion to find a consensus) > https://github.com/django/django/pull/3906 - Efficient QuerySet.__contains__ > (closed as wontfix due to the behavior change)
Thanks. Your memory is amazing :-) Since the issue keeps coming back, I think we should do one of the following: 1. make simultaneous and consistent changes to __nonzero__, __len__, and __contains__ to eliminate the "fetch the whole table" behavior when calling `if qs`, `len(qs)` and `if obj in qs` — and check if any other special methods require similar treatment 2. failing that, add .contains(), as suggested in https://code.djangoproject.com/ticket/24141 We're talking about a trade-off between preserving optimisations in existing code bases and expertise of advanced users versus doing the right thing by default for less experienced users. I think we're increasingly willing to consider changes that make Django safer to use, so perhaps what Carl said in 2015 could be open for discussion. If I forget what I know about querysets for a minute, the Principle of Least Astonishment says we should go for option 1. if qs: # test in qs isn't empty if list(qs): # fetch and cache qs, then test if it isn't empty len(qs): # count the number of objects in qs len(list(qs)): # fetch and cache qs, then count the number of objects if obj in qs: # test if qs contains obj if obj in list(qs): # fetch and cache qs, then test if qs contains obj objects = list(qs) is a well known pattern when you need to trigger the database query, perhaps because you'll do further manipulations in Python. In https://code.djangoproject.com/ticket/18702#comment:8 <https://code.djangoproject.com/ticket/18702#comment:8> Anssi says he was in favor of committing the optimized version (my option 1). Just before finalizing his patch, he changed his mind because: - "This approach optimizes use cases that are rare": well, since they keep coming up, in fact they aren't so rare - "Special casing some uses makes the code complex": sure, but the whole point of Django is to include _some_ complexity so that users have less to worry about. I'm interested in what others think :-) -- Aymeric. -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/90C68EF9-7343-44D6-9BB0-33972198685A%40polytechnique.org.
