Sortable table columns in django [closed]
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Cl开发者_如何学Goosed 6 years ago.
Improve this questionI want to have sortable columns in my tables (just like what is done for the admin changelists)....I'm looking for a solution that will be easy to implement and customize if I want.
How can I do this?
If you use pagination rather than a Javascript table sorter, it might not be sufficient or behave unexpected.
Create every column header as a link e.g.
<th><a href="?order_by=name">Name</a></th>
and in your view you check whether the order_by
parameter is set or not:
order_by = request.GET.get('order_by', 'defaultOrderField')
Model.objects.all().order_by(order_by)
Javascript? There are plenty of table sorters out there:
- http://tablesorter.com/docs/
- http://kryogenix.org/code/browser/sorttable/
- http://friedcellcollective.net/js/SortedTable/
- http://www.leigeber.com/2009/03/table-sorter/
- http://www.millstream.com.au/view/code/tablekit
I used the approach followed by the most voted answer above. But I solve the ascending/descending ordering when clicking multiple times on the column header by using a custom tag.
The tag:
from urllib.parse import urlencode
from collections import OrderedDict
@register.simple_tag
def url_replace(request, field, value, direction=''):
dict_ = request.GET.copy()
if field == 'order_by' and field in dict_.keys():
if dict_[field].startswith('-') and dict_[field].lstrip('-') == value:
dict_[field] = value
elif dict_[field].lstrip('-') == value:
dict_[field] = "-" + value
else:
dict_[field] = direction + value
else:
dict_[field] = direction + value
return urlencode(OrderedDict(sorted(dict_.items())))
Then you use this tag on your column header, like above:
<th><a href="?{% url_replace request 'order_by' 'name' '-' %}">Name</a></th>
First time you click it will sort in 'descending' order, if you click the same header again it will revert to 'ascending' order.
This approach also preserves other parameters in your URL, like page number if you are using a paginator. It requires no extra libraries. Only thing you need to make sure is that your view is sending the RequestContext to the template.
I suggest you have a look at django-tables2. It's designed to solve your exact problem. The documentation has a bunch of examples.
continuing on the most voted answer above by Felix Kling and the addition by mpaf and ngeek, when using class based views: do the sorting in the get_queryset(self) method, and use:
<th><a href="?{% url_replace view.request 'order_by' 'name' '-' %}">Name</a></th>
instead of just request in your template
精彩评论