- Author:
- flupke
- Posted:
- October 12, 2011
- Language:
- Python
- Version:
- 1.3
- Tags:
- filter admin taggit
- Score:
- 4 (after 4 ratings)
A FilterSpec that can be used to filter by taggit tags in the admin.
To use, simply import this module (for example in models.py
), and add the name of your TaggableManager field in the
list_filter attribute of your ModelAdmin class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | from django.db import models
from django.contrib.admin.filterspecs import FilterSpec, RelatedFilterSpec
from django.contrib.admin.util import get_model_from_relation
from django.db.models import Count
from taggit.managers import TaggableManager
class TaggitFilterSpec(RelatedFilterSpec):
"""
A FilterSpec that can be used to filter by taggit tags in the admin.
To use, simply import this module (for example in `models.py`), and add the
name of your :class:`taggit.managers.TaggableManager` field in the
:attr:`list_filter` attribute of your :class:`django.contrib.ModelAdmin`
class.
"""
def __init__(self, f, request, params, model, model_admin,
field_path=None):
super(RelatedFilterSpec, self).__init__(
f, request, params, model, model_admin, field_path=field_path)
other_model = get_model_from_relation(f)
if isinstance(f, (models.ManyToManyField,
models.related.RelatedObject)):
# no direct field on this model, get name from other model
self.lookup_title = other_model._meta.verbose_name
else:
self.lookup_title = f.verbose_name # use field name
rel_name = other_model._meta.pk.name
self.lookup_kwarg = '%s__%s__exact' % (self.field_path, rel_name)
self.lookup_kwarg_isnull = '%s__isnull' % (self.field_path)
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.lookup_val_isnull = request.GET.get(
self.lookup_kwarg_isnull, None)
# Get tags and their count
through_opts = f.through._meta
count_field = ("%s_%s_items" % (through_opts.app_label,
through_opts.object_name)).lower()
queryset = getattr(f.model, f.name).all()
queryset = queryset.annotate(num_times=Count(count_field))
queryset = queryset.order_by("-num_times")
self.lookup_choices = [(t.pk, "%s (%s)" % (t.name, t.num_times))
for t in queryset]
# HACK: we insert the filter at the beginning of the list to avoid the manager
# to be associated with a RelatedFilterSpec
FilterSpec.filter_specs.insert(0, (lambda f: isinstance(f, TaggableManager),
TaggitFilterSpec))
|
More like this
- Serialize a model instance by chriswedgwood 1 week, 6 days ago
- Automatically setup raw_id_fields ForeignKey & OneToOneField by agusmakmun 9 months, 2 weeks ago
- Crispy Form by sourabhsinha396 10 months, 1 week ago
- ReadOnlySelect by mkoistinen 10 months, 3 weeks ago
- Verify events sent to your webhook endpoints by santos22 11 months, 2 weeks ago
Comments
Awesome, works very well and a very good idea, thanks!
#
Nice one, thanks.
#
Things seem to have changed since 1.3. Under 1.4.1 I'm getting a "No module named filterspecs" exception.
#
Please login first before commenting.