Skip to content

Fix reservation ticket counters#436

Open
egorvaganov wants to merge 3 commits into
TiBillet:mainfrom
egorvaganov:issue-432-reservation-ticket-count
Open

Fix reservation ticket counters#436
egorvaganov wants to merge 3 commits into
TiBillet:mainfrom
egorvaganov:issue-432-reservation-ticket-count

Conversation

@egorvaganov

Copy link
Copy Markdown

Summary

Fix reservation ticket counters displayed in the account reservations page.

Changes

  • add valid_tickets_count
  • add cancelled_tickets_count
  • exclude pending/cancelled tickets from valid count
  • update reservation template
  • add pytest coverage for all counter scenarios

Tests

poetry run pytest tests/pytest/test_reservation_valid_tickets_count.py -v

@Nasjoe

Nasjoe commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Hello!
Thank you so much for this PR!
It'll be really useful :)

I noticed a minor N+1 performance issue.
Do you want to look into this? (Probably using an annotation.) Or do you want us to handle it?
Thank you very much!

@egorvaganov

egorvaganov commented Jul 6, 2026

Copy link
Copy Markdown
Author

Hi! Thanks for catching that 🙏

Fixed the N+1 by adding an annotation in MyAccount.my_reservations() (BaseBillet/views.py):

.annotate(
    annotated_valid_count=Count(
        'tickets', filter=Q(tickets__status__in=[Ticket.NOT_SCANNED, Ticket.SCANNED])
    ),
    annotated_cancelled_count=Count(
        'tickets', filter=Q(tickets__status=Ticket.CANCELED)
    ),
)

This computes both counts for all reservations in a single query instead of two queries per reservation.

I kept the existing Reservation.valid_tickets_count() / cancelled_tickets_count() methods on the model as-is, since they're still used elsewhere (single-object access, tests). I used different attribute names for the annotations (annotated_valid_count / annotated_cancelled_count) rather than reusing the method names, to avoid Django silently shadowing the methods on instances built from this queryset — that would otherwise make .valid_tickets_count() raise TypeError: 'int' object is not callable for any code still calling it as a method.

Also added a regression test that builds the same annotated queryset and asserts it matches the model methods' output on a mixed set of ticket statuses, so any future drift between the two would be caught by CI.

Updated reservations.html to use the annotated fields instead of calling the methods.

Let me know if you'd prefer a different approach!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants