How can I add a custom filter to django admin (the filters that appear on the right side of a model dashboard)? I know its easy to include a filter based on a field of that model, but what about a "calculated" field like this:
class NewsItem(models.Model): headline = models.CharField(max_length=4096, blank=False) byline_1 = models.CharField(max_length=4096, blank=True) dateline = models.DateTimeField(help_text=_("date/time that appears on article")) body_copy = models.TextField(blank=False) when_to_publish = models.DateTimeField(verbose_name="When to publish", blank=True, null=True) # HOW CAN I HAVE "is_live" as part of the admin filter? It's a calculated state!! def is_live(self): if self.when_to_publish is not None: if ( self.when_to_publish < datetime.now() ): return """ <img alt="True" src="/media/img/admin/icon-yes.gif"/> """ else: return """ <img alt="False" src="/media/img/admin/icon-no.gif"/> """ is_live.allow_tags = True
class NewsItemAdmin(admin.ModelAdmin): form = NewsItemAdminForm list_display = ('headline', 'id', 'is_live') list_filter = ('is_live') # how can i make this work??
Python Django filter contains The contains filter in Django returns all the objects that carry case-sensitive strings in the given field.
Django's Admin is amazing. A built-in and fully functional interface that quickly gets in and allows data entry is priceless. Developers can focus on building additional functionality instead of creating dummy interfaces to interact with the database.
One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.
Thanks to gpilotino for giving me the push into the right direction for implementing this.
I noticed the question's code is using a datetime to figure out when its live . So I used the DateFieldFilterSpec and subclassed it.
from django.db import models from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec,DateFieldFilterSpec from django.utils.encoding import smart_unicode from django.utils.translation import ugettext as _ from datetime import datetime class IsLiveFilterSpec(DateFieldFilterSpec): """ Adds filtering by future and previous values in the admin filter sidebar. Set the is_live_filter filter in the model field attribute 'is_live_filter'. my_model_field.is_live_filter = True """ def __init__(self, f, request, params, model, model_admin): super(IsLiveFilterSpec, self).__init__(f, request, params, model, model_admin) today = datetime.now() self.links = ( (_('Any'), {}), (_('Yes'), {'%s__lte' % self.field.name: str(today), }), (_('No'), {'%s__gte' % self.field.name: str(today), }), ) def title(self): return "Is Live" # registering the filter FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'is_live_filter', False), IsLiveFilterSpec))
To use you can put the above code into a filters.py, and import it in the model you want to add the filter to
you have to write a custom FilterSpec (not documentend anywhere). Look here for an example:
http://www.djangosnippets.org/snippets/1051/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With