Reputation: 1802
I have implemented ordering in a generic ListView:
class CarList(LoginRequiredMixin, ListView):
model = Car
paginate_by = 30
ordering = 'car_id_internal'
def get_ordering(self):
return self.request.GET.get('ordering', 'car_id_internal')
def get_context_data(self, *args, **kwargs):
context = super(CarList, self).get_context_data(*args, **kwargs)
context['current_order'] = self.get_ordering()
return context
And in my template:
<thead>
<tr>
<th><a href="{% url 'car_list' %}?ordering=car_id_internal">Internal car ID</a></th>
<th><a href="{% url 'car_list' %}?ordering=type">Type</a></th>
<th><a href="{% url 'car_list' %}?ordering=brand">Brand</a></th>
</tr>
</thead>
This works fine, however I would like for user to be able to reverse the order from ascending to descending when they click on the column header again. Is that possible with Django? I'm using Django 1.9.
I hope someone can help.
Upvotes: 3
Views: 3245
Reputation: 6096
You need to use another variable for determining the asc/desc ordering. Depending on which is currently selected the template should alternate the links. In the view, you reverse the ordering by adding a dash before the field's name. Try the following:
class CarList(ListView):
model = Car
paginate_by = 30
ordering = 'car_id_internal'
def get_ordering(self):
self.order = self.request.GET.get('order', 'asc')
selected_ordering = self.request.GET.get('ordering', 'car_id_internal')
if self.order == "desc":
selected_ordering = "-" + selected_ordering
return selected_ordering
def get_context_data(self, *args, **kwargs):
context = super(CarList, self).get_context_data(*args, **kwargs)
context['current_order'] = self.get_ordering()
context['order'] = self.order
return context
And the template:
<table>
<tr>
<th><a href="{% url 'car_list' %}?ordering=car_id_internal&order={% if order == 'desc' %}asc{% else %}desc{% endif %}">Internal car ID</a></th>
<th><a href="{% url 'car_list' %}?ordering=type&order={% if order == 'desc' %}asc{% else %}desc{% endif %}">Type</a></th>
<th><a href="{% url 'car_list' %}?ordering=brand&order={% if order == 'desc' %}asc{% else %}desc{% endif %}">Brand</a></th>
</tr>
{% for car in object_list %}
<tr>
<td>{{car.id}}</td>
<td>{{car.type}}</td>
<td>{{car.brand}}</td>
</tr>
{% endfor %}
Upvotes: 6