Monday 31 May 2021

Django Custom Queryset managers: Implicit chained filter()?

In Django, when it comes to M2M relationships, we know that these two queries:

# 1
MyModel.objects.filter(othermodel__attr1="someval1", othermodel__attr2="someval2")
# 2
MyModel.objects.filter(othermodel__attr1="someval1").filter(othermodel__attr2="someval2")

Will not necessarily return the same results (docs).

I've recently started utilizing custom QuerySet managers and it suddenly dawned on me that I may get this undesired behavior (for me at least) if I'm doing something like this:

# defined as customobjects = MyModelQuerySet.as_manager() in `MyModel`

class MyModelQuerySet(models.QuerySet): 
      def method1(self):
          return self.filter(othermodel__attr1="someval1")
      
      def method2(self):
          return self.filter(othermodel__attr2="someval2")

and using MyModelQuerySet like this:

results = MyModel.customobjects.method1().method2()

Then I may be getting the behavior of chained filters. For me this makes using a custom QuerySet manager completely useless as I need an AND behavior most of the time. But I'm not sure this is indeed the behaviour. If it is, are there are any workarounds while using managers? (I want the ability to flexibly use different filters and mix and match them with managers, but I don't want the chained filters behavior)



from Django Custom Queryset managers: Implicit chained filter()?

No comments:

Post a Comment