Due to some restrictions in a project I'm working on, I had to replace Django's QuerySet class with a custom one.
QuerySet objects can have their methods chained (eg QuerySet().filter(...).exclude(...)
and so on), so in my implementation, every method simply returns self
. So my class looks like this:
class MyQuerySet:
...
def filter(self, *args, **kwargs):
# Do some stuff and then:
return self
This way I imitated Django's QuerySet behaviour.
However, looking at the Django code, I noticed that instead of returning self
, QuerySet's methods return a cloned object every time they are called. It looks like this (removed unnecessary stuff):
class QuerySet(...):
...
def filter(self, *args, **kwargs):
clone = self._clone()
# Do some stuff and then
return clone
def _clone(self,...):
klass = self.__class__
obj = klass(...)
return obj
So basically, every time a method is called, QuerySet will clone itself, instantiate a new object and return it.
My question is: WHY? Is my way wrong?
My fear is that the way I do it, something might break, otherwise I can't explain why Django team did what it did.