mirror of
https://github.com/pretix/pretix.git
synced 2026-05-10 16:04:02 +00:00
Fix performance issue in filtering checkin list (Z#23170917) (#4607)
* Fix performance issue in filtering checkin list * remove test
This commit is contained in:
@@ -141,7 +141,7 @@ class CheckinList(LoggedModel):
|
|||||||
return self.positions_query(ignore_status=False)
|
return self.positions_query(ignore_status=False)
|
||||||
|
|
||||||
@scopes_disabled()
|
@scopes_disabled()
|
||||||
def positions_inside_query(self, ignore_status=False, at_time=None):
|
def _filter_positions_inside(self, qs, at_time=None):
|
||||||
if at_time is None:
|
if at_time is None:
|
||||||
c_q = []
|
c_q = []
|
||||||
else:
|
else:
|
||||||
@@ -149,7 +149,7 @@ class CheckinList(LoggedModel):
|
|||||||
|
|
||||||
if "postgresql" not in settings.DATABASES["default"]["ENGINE"]:
|
if "postgresql" not in settings.DATABASES["default"]["ENGINE"]:
|
||||||
# Use a simple approach that works on all databases
|
# Use a simple approach that works on all databases
|
||||||
qs = self.positions_query(ignore_status=ignore_status).annotate(
|
qs = qs.annotate(
|
||||||
last_entry=Subquery(
|
last_entry=Subquery(
|
||||||
Checkin.objects.filter(
|
Checkin.objects.filter(
|
||||||
*c_q,
|
*c_q,
|
||||||
@@ -202,7 +202,7 @@ class CheckinList(LoggedModel):
|
|||||||
.values("position_id", "type", "datetime", "cnt_exists_after")
|
.values("position_id", "type", "datetime", "cnt_exists_after")
|
||||||
.query.sql_with_params()
|
.query.sql_with_params()
|
||||||
)
|
)
|
||||||
return self.positions_query(ignore_status=ignore_status).filter(
|
return qs.filter(
|
||||||
pk__in=RawSQL(
|
pk__in=RawSQL(
|
||||||
f"""
|
f"""
|
||||||
SELECT "position_id"
|
SELECT "position_id"
|
||||||
@@ -214,6 +214,10 @@ class CheckinList(LoggedModel):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@scopes_disabled()
|
||||||
|
def positions_inside_query(self, ignore_status=False, at_time=None):
|
||||||
|
return self._filter_positions_inside(self.positions_query(ignore_status=ignore_status), at_time=at_time)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def positions_inside(self):
|
def positions_inside(self):
|
||||||
return self.positions_inside_query(None)
|
return self.positions_inside_query(None)
|
||||||
|
|||||||
@@ -1967,7 +1967,7 @@ class CheckinListAttendeeFilterForm(FilterForm):
|
|||||||
if s == '1':
|
if s == '1':
|
||||||
qs = qs.filter(last_entry__isnull=False)
|
qs = qs.filter(last_entry__isnull=False)
|
||||||
elif s == '2':
|
elif s == '2':
|
||||||
qs = qs.filter(pk__in=self.list.positions_inside.values_list('pk'))
|
qs = self.list._filter_positions_inside(qs)
|
||||||
elif s == '3':
|
elif s == '3':
|
||||||
qs = qs.filter(last_entry__isnull=False).filter(
|
qs = qs.filter(last_entry__isnull=False).filter(
|
||||||
Q(last_exit__isnull=False) & Q(last_exit__gte=F('last_entry'))
|
Q(last_exit__isnull=False) & Q(last_exit__gte=F('last_entry'))
|
||||||
|
|||||||
@@ -228,6 +228,7 @@ def checkin_list_env():
|
|||||||
# checkin
|
# checkin
|
||||||
Checkin.objects.create(position=op_a1_ticket, datetime=now() + timedelta(minutes=1), list=cl)
|
Checkin.objects.create(position=op_a1_ticket, datetime=now() + timedelta(minutes=1), list=cl)
|
||||||
Checkin.objects.create(position=op_a3_ticket, list=cl)
|
Checkin.objects.create(position=op_a3_ticket, list=cl)
|
||||||
|
Checkin.objects.create(position=op_a3_ticket, list=cl, type="exit")
|
||||||
|
|
||||||
return event, user, orga, [item_ticket, item_mascot], [order_pending, order_a1, order_a2, order_a3], \
|
return event, user, orga, [item_ticket, item_mascot], [order_pending, order_a1, order_a2, order_a3], \
|
||||||
[op_pending_ticket, op_a1_ticket, op_a1_mascot, op_a2_ticket, op_a3_ticket], cl
|
[op_pending_ticket, op_a1_ticket, op_a1_mascot, op_a2_ticket, op_a3_ticket], cl
|
||||||
@@ -260,8 +261,10 @@ def test_checkins_list_ordering(client, checkin_list_env, order_key, expected):
|
|||||||
@pytest.mark.django_db
|
@pytest.mark.django_db
|
||||||
@pytest.mark.parametrize("query, expected", [
|
@pytest.mark.parametrize("query, expected", [
|
||||||
('status=&item=&user=', ['A1Ticket', 'A1Mascot', 'A2Ticket', 'A3Ticket']),
|
('status=&item=&user=', ['A1Ticket', 'A1Mascot', 'A2Ticket', 'A3Ticket']),
|
||||||
('status=1&item=&user=', ['A1Ticket', 'A3Ticket']),
|
|
||||||
('status=0&item=&user=', ['A1Mascot', 'A2Ticket']),
|
('status=0&item=&user=', ['A1Mascot', 'A2Ticket']),
|
||||||
|
('status=1&item=&user=', ['A1Ticket', 'A3Ticket']),
|
||||||
|
('status=2&item=&user=', ['A1Ticket']),
|
||||||
|
('status=3&item=&user=', ['A3Ticket']),
|
||||||
('status=&item=&user=a3dummy', ['A3Ticket']), # match order email
|
('status=&item=&user=a3dummy', ['A3Ticket']), # match order email
|
||||||
('status=&item=&user=a3dummy', ['A3Ticket']), # match order email,
|
('status=&item=&user=a3dummy', ['A3Ticket']), # match order email,
|
||||||
('status=&item=&user=a4', ['A3Ticket']), # match attendee name
|
('status=&item=&user=a4', ['A3Ticket']), # match attendee name
|
||||||
|
|||||||
Reference in New Issue
Block a user