[Django]-In Django, how do I gracefully add a queryset filter to a large group or all members of an object?

3👍

You’re looking for model managers.

Something like:

class MediaItemManager(models.Manager):
    def get_queryset(self):
        return super(MediaItemManager, self).get_queryset().filter(...)

You can set that as the default manager on your model like this:

class MediaItem(models.Model):
    objects = MediaItemManager()
    all_objects = models.Manager()

You can ensure this doesn’t affect the admin by specifying get_queryset on your ModelAdmin subclass:

class MyModelAdmin(admin.ModelAdmin):
    def get_queryset(self, request):
        qs = self.model.all_objects.get_queryset()
        ordering = self.get_ordering(request)
        if ordering:
            qs = qs.order_by(*ordering)
        return qs

This is fairly unfortunate duplication of the base get_queryset method, since there’s no way to override the admin’s manager explicitly. A better alternative would probably be to name your custom manager filtered_objects, and use the default manager as objects.

3👍

That is exactly what custom model managers are for. Define a manager subclass and override get_query_set with your query. Then, you’ll need to explicitly define a default manager first, then call your custom one objects, and it should just work.

Note, even though you can do this, I would advise against it. At the very least, call your custom manager something else – eg restricted – and do a search and replace across your code to replace references to objects to the custom version. That allows people reading your codeto realise that the query is not the standard one.

Leave a comment