- Author:
- whiteinge
- Posted:
- February 4, 2008
- Language:
- JavaScript
- Version:
- Not specified
- Score:
- 3 (after 3 ratings)
Ever wanted to add an atypical field lookup to the Django Admin list_filter filters, like __isnull
or __in
? This jQuery snippet allows you to do just that.
Since you can access those additional filters by directly typing them into in the Admin URL, the tricky part is to add those to the regular list_filter display. A lot of this code is spent checking on querystring matches which is ugly and error-prone -- if you see any problems or room for improvement, drop me a comment!
A suggestion of where to place this code is in templates/admin/yourapp/yourmodel/change_list.html
. Mine kinda looks like this:
{% extends "admin/change_list.html" %}
{% block content %}
<script src="/static/js/jquery-1.2.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
// the JavaScript posted in this snippet
</script>
{{ block.super }}
{% endblock %}
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 | $(document).ready(function() {
function customFilter(heading, filter, text) {
var filtergroup = $('#changelist-filter h3:contains("'+ heading +'")').next('ul');
qs = window.location.search;
// if we're already filtering by a sibling (that isn't "All")
if (filtergroup.children('li:first').siblings().is('.selected')) {
// remove sibling querystring from custom filter querystring
var filterBase = filter.substr(0, filter.indexOf('_'));
var siblingQs = qs.substr(qs.indexOf(filterBase), qs.indexOf('&', qs.indexOf(filterBase)));
if (!siblingQs) {
siblingQs = qs.slice(qs.indexOf(filterBase), qs.length);
}
qs = qs.replace(siblingQs, '');
qs = qs + '&' + filter;
} else {
// no current filters, make new
if (!qs || qs == '?') {
qs = '?' + filter;
// already filtering by custom filter, ignore
} else if (qs.match(filter)) {
qs = qs;
// current filters, append
} else {
qs = qs + '&' + filter;
}
}
filtergroup.append('<li><a href="'+ qs +'">'+ text +'</a></li>');
var currentfilter = filtergroup.children('li:last');
if (window.location.search.match(filter)) {
currentfilter.addClass('selected');
currentfilter.siblings().each(function(){
$(this).removeClass('selected');
$(this).children('a').attr('href', function() {
return this.href.replace(filter, '');
});
});
}
}
// Usage examples. Takes three arguments.
// 1. the exact text above your list_display section
// 2. the custom field lookup (careful with weird characters here)
// 3. the text you want the new filter to show up as
customFilter('By affiliation', 'school__in=A,B', 'School A or B');
customFilter('By affiliation', 'school__isnull=True', 'No school');
});
|
More like this
- Django Collapsed Stacked Inlines by applecat 1 year, 10 months ago
- Django Collapsed Stacked Inlines by mkarajohn 3 years, 11 months ago
- Dynamically adding forms to a formset. OOP version. by halfnibble 9 years, 7 months ago
- Convert multiple select for m2m to multiple checkboxes in django admin form by abidibo 11 years, 8 months ago
- Django admin inline ordering - javascript only implementation by ojhilt 12 years ago
Comments
In your example you have set 'By affiliation' as the heading. How do you get this to appear above yout list_display section?
For example I want to use 'By LEA' but when I set this as the heading nothing appears in the filters. However if I set the heading to an already existing heading then my options appear.
Thanks
#
Please login first before commenting.