Django global filter

Viewed 1149

Is there a way to filter globally a Django model? We need to set a filter in a single place so that it gets applied in all queries generated by Django ORM including related objects lookups etc. Example:

class A(Model):
    n = IntegerField()

class B(Model):
    a = ForeignKey(A)

We want to set on A a global filter id__gte=10 (static to make it simple). The filter must be then automatically applied also when doing related queries, e.g.

B.objects.filter(a__n=123)  # this code cannot be modified

should expand somehow magically to an equivalent of

B.objects.filter(a__n=123, a__id__gte=10)

We can change models, managers, querysets but we cannot change the code where objects are actually queried (a lot of code, third party apps, generic API).

2 Answers

What about creating a view in the database with the filter and create a Django model pointing to the view?

You should make a custom manager and modify an initial QuerySet. Check out the docs.

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(author='Roald Dahl')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.

Then you should use your custom manager (dahl_objects) instead of objects and all queries will be modified.

Or you can override objects manager itself

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = DahlBookManager() # The Dahl-specific manager
Related