knuckfubuck
knuckfubuck

Reputation: 969

Custom Manager to filter objects on site but not in admin?

I followed this example and it works great but I'm wondering if I can put in an exception so that when I am in the admin all objects show up (active and inactive). This might be simple but I can't find how to do it in the docs.

Here's what my manager looks like now:

class ShareManager(models.Manager):
    def get_query_set(self):
        return super(ShareManager, self).get_query_set().filter(active=True)

Upvotes: 8

Views: 2101

Answers (1)

Davor Lucic
Davor Lucic

Reputation: 29390

There are several solutions that come to mind:

  1. define what queryset to use for change list with ModelAdmin.queryset().

  2. install 2 managers on your model, the first one that admin finds will be used as the default one AFAIK.

    class SomeThing(models.Model):
       objects = models.Manager()
       shares = ShareManager()
    
  3. add new method on your custom manager that returns only active stuff and leave get_query_set as it is by default.

    class ShareManager(models.Manager):
        def get_active_items(self):
            return self.get_query_set().filter(active=True)
    

Follow-up

I think the most suitable solution in your case would be combining #1 and variation of #2.

Set your custom manager as objects so everyone can access it (I think this should work for your reusability problem) and also install default manager on your model and use it in ModelAdmin.queryset().

    class SomeThing(models.Model):
       objects = ShareManager()
       admin_objects = models.Manager()

I should have included ModelAdmin.queryset() method example too, so here it is.

    def queryset(self, request):
        qs = self.model.admin_objects.get_query_set()
        # TODO: this should be handled by some parameter to the ChangeList.
        # otherwise we might try to *None, which is bad ;)
        ordering = self.ordering or () 
        if ordering:
            qs = qs.order_by(*ordering)
        return qs

Note the line qs = self.model.admin_objects.get_query_set() is working with admin_objects which is the instance of plain manager and includes unpublished items.

The rest of this implementation of queryset method is default Django's implementation which usually calls qs = self.model._default_manager.get_query_set().

I hope this clears things up a bit.

Upvotes: 9

Related Questions