﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
26379	Document that first filter() chained to a RelatedManager is sticky	Balázs Oroszi	Annabelle Wiegart	"Given the model in a ""testapp"" app:

{{{
############################
from django.db import models

class Blog(models.Model):
    title = models.CharField(max_length=100)
    # subscribers - related from Person
    # subscriptions - related from Subscription
    
    def __str__(self):
        return self.title

class Person(models.Model):
    name = models.CharField(max_length=100)
    subscribed_blogs = models.ManyToManyField(Blog, related_name=""subscribers"", through=""Subscription"")
    # subscriptions - related from Subscription
    
    def __str__(self):
        return self.name

class Subscription(models.Model):
    person = models.ForeignKey(Person, related_name=""subscriptions"")
    blog = models.ForeignKey(Blog, related_name=""subscriptions"")
    subscribed_date = models.DateField()
    
    def __str__(self):
        return ''.join([self.person.name, "" - "", self.blog.title])
############################
}}}

When I filter ""subscribers"" of a Blog instance, the results are not consistent.
Here is the code demonstrating the effect:

{{{
############################
from testapp.models import *
from datetime import datetime

adam = Person.objects.create(name=""Adam"")
blog_1 = Blog.objects.create(title=""Blog 1"")
blog_2 = Blog.objects.create(title=""Blog 2"")
Subscription.objects.create(person=adam, blog=blog_1, subscribed_date=datetime(2016,1,10))
Subscription.objects.create(person=adam, blog=blog_2, subscribed_date=datetime(2016,1,20))

queryparams = {""subscriptions__subscribed_date__gt"": datetime(2016,1,15)}

q1 = blog_1.subscribers.filter(**queryparams)
q2 = blog_1.subscribers.all().filter(**queryparams)
q3 = blog_1.subscribers.get_queryset().filter(**queryparams)
print(q1.query)
print(q1)
print(q2.query)
print(q2)
print(q3.query)
print(q3)

print(""--------------------------"")

q1 = blog_1.subscribers.filter().filter(**queryparams)
q2 = blog_1.subscribers.all().all().filter(**queryparams)
q3 = blog_1.subscribers.get_queryset().all().filter(**queryparams)
print(q1.query)
print(q1)
print(q2.query)
print(q2)
print(q3.query)
print(q3)
############################
}}}

The output is:

{{{
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND ""testapp_subscription"".""subscribed_date"" > 2016-01-15)
[]
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND ""testapp_subscription"".""subscribed_date"" > 2016-01-15)
[]
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND ""testapp_subscription"".""subscribed_date"" > 2016-01-15)
[]
--------------------------
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") INNER JOIN ""testapp_subscription"" T4 ON (""testapp_person"".""id"" = T4.""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND T4.""subscribed_date"" > 2016-01-15)
[<Person: Adam>]
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") INNER JOIN ""testapp_subscription"" T4 ON (""testapp_person"".""id"" = T4.""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND T4.""subscribed_date"" > 2016-01-15)
[<Person: Adam>]
SELECT ""testapp_person"".""id"", ""testapp_person"".""name"" FROM ""testapp_person"" INNER JOIN ""testapp_subscription"" ON (""testapp_person"".""id"" = ""testapp_subscription"".""person_id"") INNER JOIN ""testapp_subscription"" T4 ON (""testapp_person"".""id"" = T4.""person_id"") WHERE (""testapp_subscription"".""blog_id"" = 1 AND T4.""subscribed_date"" > 2016-01-15)
[<Person: Adam>]
}}}

The first set of queries simply ""AND"" the filter params with the ""subscribers"" RelatedManager's inherent related-filtering, while the second set of queries do a separate chain filtering.
This is exactly the kind of situation that is described in the django docs (with the blogs, ""Lennon"" and ""2008""):
https://docs.djangoproject.com/en/dev/topics/db/queries/#spanning-multi-valued-relationships

I believe the second set of queries should be the correct one, and that should be happening also in the first set of queries, but that is not what is happening.
"	Bug	closed	Documentation	1.9	Normal	fixed		yaiche.amin@…	Ready for checkin	1	0	0	0	0	0
