0

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 %}
orzel
  • 15
  • 1
  • 7

2 Answers2

1

You can save the order of sorting without JS by adding order to end of href in pagination links. Like:

{% if page_obj.has_previous %}
    <a href="{{ request.path }}?page= {{ page_obj.previous_page_number }}&order={{order}}">previous</a>
{% endif %}
Oleh
  • 43
  • 7
0

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.

hpca01
  • 370
  • 4
  • 15
  • Hm the only possibility is to do this with Ajax or JS? I tought about extend url with something like this: "mypage/votes/?page=&order_by="" "Next" and "Previous" buttons will only change a "page=" in url and "Ordering" select field will only change a "order_by". Then this captured values in view will set ordering. I hope it's clearly explained. :) – orzel Jul 04 '18 at 19:48
  • I get where your coming from, its a separation of concerns bit here, depending on how much your server is going to scale. Sorting data is operation that is still costly depending on size and other variables. In this day and age, you can leverage the browser of the client to do client side rendering using JS. Of course it is still costly, in that you have to write there resource library or JS to do it. Think about having to create url endpoints for all kinds of routing only to process and send out the data again...that is too much work. – hpca01 Jul 04 '18 at 20:03
  • You right, I get it. Lot of data means lot of operation = low performance, that's why better to use JS. Now question: should I looking for ready solutions or make own? I mean when developing web It's better to make own or use some existing solution, like ready libraries? I think my project don't need some complicated functions, just simple sorting by columns name. – orzel Jul 04 '18 at 20:15
  • yeah for basic datatable display there is a library called datatablejs, the documentation is also very helpful. Take a look at it and if you still decide to do more of the ops on the server end, you can leverage the Jquery onchange function to send off ajax requests to query more data. What you want to keep in mind is that you do not want to query the server for info more than you need to in order to get your view populated. – hpca01 Jul 04 '18 at 21:17