DEV Community

Juhana Jauhiainen
Juhana Jauhiainen

Posted on • Originally published at juhanajauhiainen.com

Use a Model Manager to filter queryset by default in Django

How can you filter a queryset by default so that no matter where you use the model, the filter will be applied?

This can be achieved by creating a custom Manager and overriding its get_queryset method.

For example, if we have a soft delete feature in our app implemented by adding a deleted column, we can force only returing non-deleted objects by creating a custom model manager which filters for deleted=false

class BookManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().filter(deleted=False)

class Book(models.Model):
    # ...
    deleted = models.BooleanField(default=False)
    objects = BookManager()
Enter fullscreen mode Exit fullscreen mode

Now everytime you query Book objects in your app with Book.objects , you will only receive books that haven't been deleted.

Links

Model managers

Top comments (1)

Collapse
 
ilyas_jumadurdyew_4041a28 profile image
Elias Jumadurdyew

Will it also work for related items?

Let's say we have an Author model and a Book model wich contains author as a foreign key

class Author(models.Model):
    title = models.CharField(
        max_length=120, blank=False, null=False, unique=True
    )


class Book(models.Model):
    author = models.ForeignKey(
        "Author", related_name="author_books", on_delete=models.CASCADE
    )
    title = models.CharField(
        max_length=120, blank=False, null=False
    )
    deleted = models.BooleanField(
        default=False, blank=False, null=False
    )
Enter fullscreen mode Exit fullscreen mode

So the question is, will related items fetch exclude deleted Book items?

author = Author.objects.all().prefetch_related("author_books").first()
# Will books select exclude deleted books?
books = list(author.author_books.all().values())
Enter fullscreen mode Exit fullscreen mode