#5833: Custom FilterSpecs
-------------------------------------+-------------------------------------
Reporter: | Owner: jkocherhans
Honza_Kral | Status: assigned
Type: New | Component: contrib.admin
feature | Severity: Normal
Milestone: | Keywords: nfa-someday
Version: SVN | list_filter filterspec nfa-
Resolution: | changelist ep2008
Triage Stage: Accepted | Has patch: 1
Needs documentation: 1 | Needs tests: 1
Patch needs improvement: 0 |
-------------------------------------+-------------------------------------
Comment (by julien):
OK, so I've tweaked the patch some more and tried to come up with an API
that's (hopefully) simple and easy to use, introducing a new
`SimpleFilterSpec` class. Here's an example:
{{{
#!python
# The model
class Person(models.Model):
name = models.CharField(max_length=100)
age = models.PositiveIntegerField()
from django.contrib.admin.filterspecs import SimpleFilterSpec
# The custom filter spec
class AgeCategoryFilterSpec(SimpleFilterSpec):
def get_title(self):
return u'age category'
def get_choices(self, request):
return (
(u'0-19', u'0 to 19'),
(u'20-39', u'20 to 39'),
(u'40-over', u'40 and over'),
)
def get_query_set(self, cls, qs):
age_category = self.get_value()
if age_category == u'0-19':
return qs.filter(age__gte=0, age__lte=19)
if age_category == u'20-39':
return qs.filter(age__gte=20, age__lte=39)
if age_category == u'40-over':
return qs.filter(age__gte=40)
return qs
# The admin
class PersonAdmin(admin.ModelAdmin):
list_display = ('name', 'age')
list_filter = ('age', AgeCategoryFilterSpec,)
}}}
`SimpleFilterSpec` does all the boring work for you, i.e. yielding the
iterator items when rendering the template, managing the query string both
in and out, and fetching the requested value. All you need to provide is
the title and the choices, and then you can filter the queryset based on
the requested value. The lookup parameter defaults to the title slugified
(i.e. "age-category" with the example above), although you can customise
it by overriding the `get_lookup_parameter()` hook.
I think this API would cover the majority of use cases. If you want
something more eccentric then you can always directly extend the
`FilterSpec` class.
It's all implemented in the attached patch, including tests for this new
feature.
Also, here are some notable changes I've made:
* I've renamed the `choices()` method to `_choices()` as I think it feels
more like internal API, and also to avoid users mistakingly overriding it
instead of the proposed new official `get_choices()` method.
* The name of the `title()` method didn't feel right so I've renamed it
`get_title()`. Hopefully this is isn't considered backwards-incompatible
(it's easily reversible if so).
So that's it. At this stage I'd really like to get some feedback both on
the API and on the implementation approach, so please let me know what you
think. If people like it then I'll write more tests and get started with
the doc.
--
Ticket URL: <http://code.djangoproject.com/ticket/5833#comment:114>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.