> 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.

Reply via email to