From 6891da6a5a36e47b1dfb978cc3892e5c9d439454 Mon Sep 17 00:00:00 2001
From: Todd Dembrey <todd.dembrey@torchbox.com>
Date: Tue, 23 Jan 2018 15:02:34 +0000
Subject: [PATCH] enable ordering on the table including for JSON structures

---
 opentech/apply/dashboard/tables.py            |  1 +
 .../templates/dashboard/tables/table.html     |  6 ++++++
 opentech/apply/dashboard/views.py             |  2 ++
 opentech/apply/funds/models.py                | 21 +++++++++++++++++++
 4 files changed, 30 insertions(+)
 create mode 100644 opentech/apply/dashboard/templates/dashboard/tables/table.html

diff --git a/opentech/apply/dashboard/tables.py b/opentech/apply/dashboard/tables.py
index 0d568c685..4d3b529af 100644
--- a/opentech/apply/dashboard/tables.py
+++ b/opentech/apply/dashboard/tables.py
@@ -9,3 +9,4 @@ class DashboardTable(tables.Table):
     class Meta:
         model = ApplicationSubmission
         fields = ('title', 'page', 'submit_time')
+        template = "dashboard/tables/table.html"
diff --git a/opentech/apply/dashboard/templates/dashboard/tables/table.html b/opentech/apply/dashboard/templates/dashboard/tables/table.html
new file mode 100644
index 000000000..49e9c41a1
--- /dev/null
+++ b/opentech/apply/dashboard/templates/dashboard/tables/table.html
@@ -0,0 +1,6 @@
+{% extends 'django_tables2/table.html' %}
+
+{# example of how to extend the table template #}
+{% block table.tbody.row %}
+    {{ block.super }}
+{% endblock %}
diff --git a/opentech/apply/dashboard/views.py b/opentech/apply/dashboard/views.py
index 8a14705f4..b86e281c4 100644
--- a/opentech/apply/dashboard/views.py
+++ b/opentech/apply/dashboard/views.py
@@ -1,4 +1,5 @@
 from django.views.generic import ListView
+from django_tables2 import RequestConfig
 
 from opentech.apply.funds.models import ApplicationSubmission
 
@@ -12,4 +13,5 @@ class DashboardView(ListView):
     def get_context_data(self, **kwargs):
         context = super().get_context_data(**kwargs)
         context['object_list'] = DashboardTable(context['object_list'])
+        RequestConfig(self.request).configure(context['object_list'])
         return context
diff --git a/opentech/apply/funds/models.py b/opentech/apply/funds/models.py
index 9c0b27500..528c72e50 100644
--- a/opentech/apply/funds/models.py
+++ b/opentech/apply/funds/models.py
@@ -1,6 +1,8 @@
 from datetime import date
 
 from django.core.exceptions import ValidationError
+from django.db import models
+from django.db.models.expressions import RawSQL, OrderBy
 from django.contrib.postgres.fields import JSONField
 from django.db import models
 from django.db.models import Q
@@ -196,9 +198,28 @@ class Round(AbstractStreamForm):
         raise Http404()
 
 
+class JSONOrderable(models.QuerySet):
+    def order_by(self, *field_names):
+        def build_json_order_by(field):
+            if field.replace('-', '') not in REQUIRED_BLOCK_NAMES:
+                return field
+
+            if field[0] == '-':
+                descending = True
+                field = field[1:]
+            else:
+                descending = False
+            return OrderBy(RawSQL("LOWER(form_data->>%s)", (field,)), descending=descending)
+
+        field_ordering = [build_json_order_by(field) for field in field_names]
+        return super().order_by(*field_ordering)
+
+
 class ApplicationSubmission(AbstractFormSubmission):
     form_data = JSONField()
 
+    objects = JSONOrderable.as_manager()
+
     def get_data(self):
         # Updated for JSONField
         form_data = self.form_data
-- 
GitLab