On Monday, August 21, 2017 at 11:28:35 AM UTC+3, Tom Forbes wrote:
>
> > Interestingly enough, just doing a .filter(m2m_relation__foo='bar') 
> might change the results
>
> Is that not because it's a filter? Would ". 
> annotate(x=F('m2m_relation__foo'))" change the results in any way? Sorry if 
> I'm not following.
>

What's happening here is that Django generates an unconstrained join to the 
m2m_relation. Unsurprisingly that generates duplicate rows to the queryset. 
For example:

class Publisher:
    name = CharField()

class Book:
     publisher = ForeignKey(Publisher, related_name='books')

print(Publisher.objects.annotate(book_id=F('books__id')).query)
OUT: SELECT publisher.id, book.id as book_id FROM publisher JOIN book ON 
book.publisher_id = publisher.id

Now, if there are two books fo any publisher, that publisher will be 
outputted twice in the resulting queryset.

Normally you wouldn't want to do this, but even if you do this by accident, 
count() and len(qs) should return the same number. And, for .values() 
querysets this can be actually useful in some cases.

Note that it's possible to remove the select entry for the annotation, even 
if the join can't be removed in this case.

 - Anssi

-- 
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 post to this group, send email to [email protected].
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/d9f2cded-ef37-4852-8845-1fcc126457ee%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to