Search code examples
djangodjango-templatesdjango-viewsdjango-pagination

Django - pagination and sorting list


I want to make view which display list of model objects in table. I want to add sorting feature.

There is possibility to do sorting like here: https://codepen.io/imarkrige/pen/vgmij in Django?

I mean this Arrows in column names. Where on click is changing asc to desc. Next thing is to keep sorted table while changing page.

What I did for now is sort field, but it's not saving while changing pages.

My basic generic view contains:

{% block pagination %}
    {% if is_paginated %}
        <div class="pagination">
            <span class="page-links">
                {% if page_obj.has_previous %}
                    <a href="{{ request.path }}?page= {{ page_obj.previous_page_number }}">previous</a>
                {% endif %}
                <span class="page-current">
                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
                </span>
                {% if page_obj.has_next %}
                    <a href="{{ request.path }}?page={{ page_obj.next_page_number }}">next</a>
                {% endif %}
            </span>
        </div>
    {% endif %}
{% endblock %}

my view:

class VotesList(generic.ListView):
    model = Vote
    template_name = 'votes-list.html'
    paginate_by = 5

    def get_queryset(self):
        order = self.request.GET.get('orderby', 'created_date')
        new_context = Vote.objects.order_by(order)

        return new_context

    def get_context_data(self, **kwargs):
        context = super(VotesList, self).get_context_data(**kwargs)
        context['orderby'] = self.request.GET.get('orderby', 'created_date')

        return context

My template:

{% block content %}
    {% if vote_list %}

<form method="get" action="{% url 'votes-list' %}">
    <p>Sortuj: <input type="text" value={{orderby}} name="orderby"/></p>
    <p><input type="submit" name="submit" value="Zatwierdź"/></p>
</form>
        <table id="vote_list">
            <thead>
                <tr>
                    <th>Właściciel</th> 
                    <th>Grupa</th> 
                    <th>Rada</th> 
                    <th>Status</th> 
                    <th>Pytanie</th>
                    <th>Odp A</th>
                    <th>Odp B</th>
                    <th>Odp C</th>
                    <th>Odp D</th>
                    <th>Odp E</th>
                    <th>Odp F</th> 
                    <th>Data utworzenia</th>
                    <th>Data rozpoczęcia</th>
                    <th>Data zakończenia</th>
                </tr>
            </thead>
            <tbody>
                {% for vote in vote_list %}
                    <tr>
                        <td>{{ vote.user }}</td>
                        <td>{{ vote.group }}</td>
                        <td>{{ vote.council }}</td>
                        <td>{{ vote.get_status }}</td>
                        <td><a href="{{ vote.get_absolute_url }}">{{ vote.question }}</a></td>
                        <td>{{ vote.ans_a }}</td>
                        <td>{{ vote.ans_b }}</td>
                        <td>{{ vote.ans_c }}</td>
                        <td>{{ vote.ans_d }}</td>
                        <td>{{ vote.ans_e }}</td>
                        <td>{{ vote.ans_f }}</td>
                        <td>{{ vote.created_date }}</td>
                        <td>{{ vote.begin_date }}</td>
                        <td>{{ vote.finish_date }}</td>
                    </tr>
                {% endfor %}
            </tbody>
        </table>

    {% else %}
        <p>Brak głosowań!</p>
    {% endif %}
{% endblock %}

Solution

  • You can use javascript to do the sorting, particularly datatablejs can help with this. However saving the state of the sorted list between page changes will probably have to be done with cookies. This is probably easier than using ajax requests to store user preferences on "sorting" as a part of the user model.

    Here is a reference on how to make cookies: https://www.quirksmode.org/js/cookies.html

    What you probably want to do is save sort order in cookie, then read it on page load. Once read you can set the sort order that way.