From ebabd20d095f1cddf1675c958a6d452b2b5ba6cc Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Thu, 25 May 2017 17:21:33 +0200 Subject: [PATCH] [Django 1.11] Refs #481 -- Explicit sorting of NULLs --- src/pretix/control/views/checkin.py | 17 ++++++++++------- src/tests/control/test_checkins.py | 15 +++++++-------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/pretix/control/views/checkin.py b/src/pretix/control/views/checkin.py index 911681b29..871f733b6 100644 --- a/src/pretix/control/views/checkin.py +++ b/src/pretix/control/views/checkin.py @@ -1,4 +1,4 @@ -from django.db.models import Prefetch, Q +from django.db.models import F, Prefetch, Q from django.db.models.functions import Coalesce from django.views.generic import ListView @@ -68,12 +68,15 @@ class CheckInView(EventPermissionRequiredMixin, ListView): '-code': '-order__code', 'email': 'order__email', '-email': '-order__email', - 'status': 'checkins__id', - '-status': '-checkins__id', - 'timestamp': 'checkins__datetime', - '-timestamp': '-checkins__datetime', + # Set nulls_first to be consistent over databases + 'status': F('checkins__id').asc(nulls_first=True), + '-status': F('checkins__id').desc(nulls_last=True), + 'timestamp': F('checkins__datetime').asc(nulls_first=True), + '-timestamp': F('checkins__datetime').desc(nulls_last=True), 'item': 'item__name', '-item': '-item__name', - 'name': ('display_name', {'display_name': Coalesce('attendee_name', 'addon_to__attendee_name')}), - '-name': ('-display_name', {'display_name': Coalesce('attendee_name', 'addon_to__attendee_name')}), + 'name': (F('display_name').asc(nulls_first=True), + {'display_name': Coalesce('attendee_name', 'addon_to__attendee_name')}), + '-name': (F('display_name').desc(nulls_last=True), + {'display_name': Coalesce('attendee_name', 'addon_to__attendee_name')}), } diff --git a/src/tests/control/test_checkins.py b/src/tests/control/test_checkins.py index 41095b103..76119e2fc 100644 --- a/src/tests/control/test_checkins.py +++ b/src/tests/control/test_checkins.py @@ -210,12 +210,12 @@ def checkin_list_env(): ('code', ['A1Ticket', 'A1Mascot', 'A2Ticket', 'A3Ticket']), ('-email', ['A3Ticket', 'A2Ticket', 'A1Ticket', 'A1Mascot']), ('email', ['A1Ticket', 'A1Mascot', 'A2Ticket', 'A3Ticket']), - # ('-status', ['A3Ticket', 'A1Ticket', 'A1Mascot', 'A2Ticket']), - # ('status', ['A1Mascot', 'A2Ticket', 'A1Ticket', 'A3Ticket']), - # ('-timestamp', ['A1Ticket', 'A3Ticket', 'A1Mascot', 'A2Ticket']), # A1 checkin date > A3 checkin date - # ('timestamp', ['A1Mascot', 'A2Ticket', 'A3Ticket', 'A1Ticket']), - # ('-name', ['A3Ticket', 'A2Ticket', 'A1Ticket', 'A1Mascot']), - # ('name', ['A1Mascot', 'A1Ticket', 'A2Ticket', 'A3Ticket']), # mascot doesn't include attendee name + ('-status', ['A3Ticket', 'A1Ticket', 'A1Mascot', 'A2Ticket']), + ('status', ['A1Mascot', 'A2Ticket', 'A1Ticket', 'A3Ticket']), + ('-timestamp', ['A1Ticket', 'A3Ticket', 'A1Mascot', 'A2Ticket']), # A1 checkin date > A3 checkin date + ('timestamp', ['A1Mascot', 'A2Ticket', 'A3Ticket', 'A1Ticket']), + ('-name', ['A3Ticket', 'A2Ticket', 'A1Ticket', 'A1Mascot']), + ('name', ['A1Mascot', 'A1Ticket', 'A2Ticket', 'A3Ticket']), # mascot doesn't include attendee name ('-item', ['A1Ticket', 'A2Ticket', 'A3Ticket', 'A1Mascot']), ('item', ['A1Mascot', 'A1Ticket', 'A2Ticket', 'A3Ticket']), ]) @@ -259,8 +259,7 @@ def test_checkins_item_filter(client, checkin_list_env): @pytest.mark.parametrize("query, expected", [ ('status=&item=&user=&ordering=', ['A1Ticket', 'A1Mascot', 'A2Ticket', 'A3Ticket']), ('status=1&item=&user=&ordering=timestamp', ['A3Ticket', 'A1Ticket']), - # ('status=0&item=&user=&ordering=-name', ['A2Ticket', 'A1Mascot']), - # ('status=&item=Ticket&user=&ordering=checkins__datetime', ['A2Ticket', 'A3Ticket', 'A1Ticket']), + ('status=0&item=&user=&ordering=-name', ['A2Ticket', 'A1Mascot']), ]) def test_checkins_list_mixed(client, checkin_list_env, query, expected): client.login(email='dummy@dummy.dummy', password='dummy')