Hi, I noticed something strange with filtering related objects. Below is a complete sample demonstrating the problem. This is only for demonstrating the problem. Django version is 1.9.1
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. Am I missing something or does this seem like a bug? Greets, Balázs -- You received this message because you are subscribed to the Google Groups "Django users" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscr...@googlegroups.com. To post to this group, send email to django-users@googlegroups.com. Visit this group at https://groups.google.com/group/django-users. To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/9f913231-2968-4c2f-b415-973f3f521858%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.