Custom Manager query that works on QuerySets?

I have this model and manager:

class AbonnentManager(models.Manager):
    def search(self, query):
        queryset: QuerySet = self.all()
        ...
        # Do a lot of filtering on queryset
        ...
        return queryset


class Abonnent(Adresse):
    ...
    objects = AbonnentManager()

The search() method does a lot of filtering (filter()) on the queryset. This works fine, when I have a Manager object such as Abonnent.objects or verein.abonnent_set.

But I want this to also be available on any other QuerySet like filter(), all(). How can I do that?

Instead of creating a custom Manager, create a custom QuerySet. Then your QuerySet operations will be chainable. You can use QuerySet.as_manager to define objects on the model.

Thanks for your answer, @massover. Could you give a simple example how to do that? I read the documentation, but I don’t see how that would answer my question.

This is what must work:

Abonnent.objects.all().filter(...).search(...).filter(...)
                                   ^^^^^^^^^^^
class AbonnentQuerySet(models.QuerySet):
    def search(self, query):
        queryset: QuerySet = self.all()
        ...
        # Do a lot of filtering on queryset
        ...
        return queryset


class Abonnent(Adresse):
    ...
    objects = AbonnentQuerySet.as_manager()

The problem is that the manager method returns a queryset and is not chainable like you expect. If you put the method on the queryset instead, they will be chainable, and the result of .filter(...) can then call .search(...)

1 Like