Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Webstack-django-sorting Changelog
=================================

v2.3.2
------

Released on TBC

- Set default sort order on first click of a column

v2.0.0
------

Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,11 @@ The project provides examples of integration with Django and Jinja2 templates.
</tr>
```

An optional 3rd argument allows you to sort first by descending
(e.g. show most recent dates first) `{% anchor some_date _("Date") desc %}`

If your application doesn't support internationalization, you can use a
simple `{% anchor first_name Name %}`.
simple `{% anchor first_name Name %}`.

## For Jinja2 templates

Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = webstack-django-sorting
version = 2.3.1
version = 2.3.2
author = Stéphane Raimbault
author_email = stephane.raimbault@webstack.fr
description = Easy sorting of tables with Django
Expand Down
34 changes: 34 additions & 0 deletions testproj/testproj/testapp/jinja2/secret_list_some_desc.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Default list</title>
<link rel="stylesheet" href="{{ static("css/style.css") }}" />
</head>
<body>
<h2>List of files</h2>
<table>
<thead>
<tr>
<th>{{ sorting_anchor(request, "id", "File ID") }}</th>
<th>{{ sorting_anchor(request, "filename", "Filename") }}</th>
<th>{{ sorting_anchor(request, "created_on", "Date", "desc") }}</th>
<th>{{ sorting_anchor(request, "size", "Size") }}</th>
<th>{{ sorting_anchor(request, "order", "Order", "desc") }}</th>
<th>{{ sorting_anchor(request, "is_secret", "Secret?") }}</th>
</tr>
</thead>
<tbody>
{% for secret_file in sort_queryset(request, secret_files) %}
<tr>
<td>{{ secret_file.id }}</td>
<td>{{ secret_file.filename }}</td>
<td>{{ secret_file.created_on }}</td>
<td>{{ secret_file.size }}</td>
<td>{{ secret_file.order }}</td>
<td>{{ secret_file.is_secret|yesno() }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
6 changes: 6 additions & 0 deletions testproj/testproj/testapp/templates/home.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ <h2>Test views with Django template</h2>
<li>
<a href="{% url 'secret_list' %}">List of secrets</a>
</li>
<li>
<a href="{% url 'secret_list_some_desc' %}">List of secrets - date and order descending</a>
</li>
<li>
<a href="{% url 'nulls_first' %}">Nulls first</a>
</li>
Expand All @@ -23,6 +26,9 @@ <h2>Test views with Jinja template</h2>
<li>
<a href="{% url 'jinja_secret_list' %}">List of secrets</a>
</li>
<li>
<a href="{% url 'jinja_secret_list_some_desc' %}">List of secrets - date and order descending</a>
</li>
<li>
<a href="{% url 'jinja_nulls_first' %}">Nulls first</a>
</li>
Expand Down
38 changes: 38 additions & 0 deletions testproj/testproj/testapp/templates/secret_list_some_desc.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{% load static sorting_tags %}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Default list</title>
<link rel="stylesheet" href="{% static 'css/style.css' %}" />
</head>
<body>
<h2>List of files</h2>
<p>In this example the Date and Order field will be sorted DESC on first click</p>
{% autosort secret_files %}
<table>
<thead>
<tr>
<th>{% anchor id "ID" %}</th>
<th>{% anchor filename "Filename" %}</th>
<th>{% anchor created_on "Date" desc %}</th>
<th>{% anchor size "Size" %}</th>
<!-- Deliberately but "desc" to test common mistake, can be either "desc" or desc, should handle both -->
<th>{% anchor order "Order" "desc" %}</th>
<th>{% anchor is_secret "Secret?" %}</th>
</tr>
</thead>
<tbody>
{% for secret_file in secret_files %}
<tr>
<td>{{ secret_file.id }}</td>
<td>{{ secret_file.filename }}</td>
<td>{{ secret_file.created_on }}</td>
<td>{{ secret_file.size }}</td>
<td>{{ secret_file.order }}</td>
<td>{{ secret_file.is_secret|yesno }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</body>
</html>
8 changes: 8 additions & 0 deletions testproj/testproj/testapp/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def secret_list(request):
request, "secret_list.html", {"secret_files": models.SecretFile.objects.all()}
)

def secret_list_some_desc(request):
return render(
request, "secret_list_some_desc.html", {"secret_files": models.SecretFile.objects.all()}
)

def secret_list_nulls_first(request):
return render(
Expand All @@ -34,6 +38,10 @@ def jinja_secret_list(request):
request, "secret_list.jinja2", {"secret_files": models.SecretFile.objects.all()}
)

def jinja_secret_list_some_desc(request):
return render(
request, "secret_list_some_desc.jinja2", {"secret_files": models.SecretFile.objects.all()}
)

def jinja_secret_list_nulls_first(request):
return render(
Expand Down
2 changes: 2 additions & 0 deletions testproj/testproj/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
urlpatterns = [
path("", views.home, name="home"),
path("list", views.secret_list, name="secret_list"),
path("list_some_desc", views.secret_list_some_desc, name="secret_list_some_desc"),
path("nulls/first", views.secret_list_nulls_first, name="nulls_first"),
path("nulls/last", views.secret_list_nulls_last, name="nulls_last"),
path("jinja/list", views.jinja_secret_list, name="jinja_secret_list"),
path("jinja/list_some_desc", views.jinja_secret_list_some_desc, name="jinja_secret_list_some_desc"),
path(
"jinja/nulls/first",
views.jinja_secret_list_nulls_first,
Expand Down
29 changes: 20 additions & 9 deletions webstack_django_sorting/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,30 @@
from . import settings


def render_sort_anchor(request, field_name, title):
def render_sort_anchor(request, field_name, title, default_direction):
get_params = request.GET.copy()
sort_by = get_params.get("sort", None)
sort_by = get_params.get("sort", None)
if sort_by == field_name:
# Render anchor link to next direction
current_direction = settings.SORT_DIRECTIONS.get(
get_params.get("dir", ""), settings.SORT_DIRECTIONS[""]
)
icon = current_direction["icon"]
next_direction_code = current_direction["next"]

dir = get_params.get("dir")

if dir == "asc":
icon = settings.DEFAULT_SORT_UP
elif dir == "desc":
icon = settings.DEFAULT_SORT_DOWN
else:
icon = ""

# Mapping of direction transitions based on the default sort direction
transition_map = {
"asc": {"asc": "desc", "desc": "", "": "asc"},
"desc": {"desc": "asc", "asc": "", "": "desc"}
}
next_direction_code = transition_map[default_direction].get(dir, "")

else:
icon = ""
next_direction_code = "asc"
next_direction_code = default_direction

# Not usual dict (can't update to replace)
get_params["sort"] = field_name
Expand Down
4 changes: 2 additions & 2 deletions webstack_django_sorting/jinja2_globals.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from . import common


def sorting_anchor(request, field_name, title):
return Markup(common.render_sort_anchor(request, field_name, title))
def sorting_anchor(request, field_name, title, default_sort_order="asc"):
return Markup(common.render_sort_anchor(request, field_name, title, default_sort_order))


def sort_queryset(request, queryset, **context_var):
Expand Down
8 changes: 1 addition & 7 deletions webstack_django_sorting/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,4 @@

DEFAULT_SORT_UP = getattr(settings, "DEFAULT_SORT_UP", " &uarr;")
DEFAULT_SORT_DOWN = getattr(settings, "DEFAULT_SORT_DOWN", " &darr;")
INVALID_FIELD_RAISES_404 = getattr(settings, "SORTING_INVALID_FIELD_RAISES_404", False)

SORT_DIRECTIONS = {
"asc": {"icon": DEFAULT_SORT_UP, "next": "desc"},
"desc": {"icon": DEFAULT_SORT_DOWN, "next": ""},
"": {"icon": "", "next": "asc"},
}
INVALID_FIELD_RAISES_404 = getattr(settings, "SORTING_INVALID_FIELD_RAISES_404", False)
10 changes: 7 additions & 3 deletions webstack_django_sorting/templatetags/sorting_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def anchor(parser, token):
"""
Parses a tag that's supposed to be in this format '{% anchor field title %}'
Title may be a "string", _("trans string"), or variable
Optional - default sort direction to desc '{% anchor field title "desc" %}'
"""
bits = [b for b in token.split_contents()]
if len(bits) < 2:
Expand All @@ -33,9 +34,11 @@ def anchor(parser, token):
title_is_var = True
except IndexError:
title = bits[1].capitalize()

default_sort_order = "desc" if len(bits) >= 4 and bits[3].strip("'\"") == "desc" else "asc"

return SortAnchorNode(
bits[1].strip(), title.strip(), title_is_var, title_is_translatable
bits[1].strip(), title.strip(), title_is_var, title_is_translatable, default_sort_order
)


Expand All @@ -52,11 +55,12 @@ class SortAnchorNode(template.Node):

"""

def __init__(self, field, title, title_is_var, title_is_translatable):
def __init__(self, field, title, title_is_var, title_is_translatable, default_sort_order):
self.field = field
self.title = title
self.title_is_var = title_is_var
self.title_is_translatable = title_is_translatable
self.default_sort_order = default_sort_order

def render(self, context):
if self.title_is_var:
Expand All @@ -66,7 +70,7 @@ def render(self, context):
else:
display_title = self.title

return common.render_sort_anchor(context["request"], self.field, display_title)
return common.render_sort_anchor(context["request"], self.field, display_title, self.default_sort_order)


def autosort(parser, token):
Expand Down