fix: remove expand_fields from conference list and add server-side pagination#19
Merged
agonza1 merged 1 commit intoApr 8, 2026
Conversation
…gination
Part A — Remove expand_fields from conference list:
- List view no longer inlines participants/issues (N+1 eliminated)
- Detail view (single conference) still returns expanded fields
Part B — Add opt-in server-side pagination:
- ?limit= and ?offset= params on conferences, sessions, participants, events
- Returns { results: [...], count: N } when pagination params are present
- Returns original { data: [...] } format when no params (backward compatible)
- Default limit=50, max=200, with input validation
Part C — Fix BaseModel.filter() eager materialization:
- Removed .exists() call (result was discarded)
- Removed eager for-loop that called prepare() on every row
- filter() now returns a lazy QuerySet so LIMIT/OFFSET work at DB level
- prepare() moved into serialize() to preserve App.prepare() behavior
Closes peermetrics#17
5 tasks
Boanerges1996
added a commit
to Boanerges1996/api
that referenced
this pull request
Apr 9, 2026
…ants_count After expand_fields was removed (PR peermetrics#19), the conference list no longer includes participants or issues arrays. This broke the dashboard charts for error/warning icons and participant counts. Adds lightweight annotations via Exists() subqueries and Count() so the list includes: - has_errors (boolean) - has_warnings (boolean) - participants_count (integer) No N+1 queries — all computed in the same SQL query.
This was referenced Apr 9, 2026
agonza1
pushed a commit
that referenced
this pull request
Apr 10, 2026
…ants_count (#22) * fix: annotate conference list with has_errors, has_warnings, participants_count After expand_fields was removed (PR #19), the conference list no longer includes participants or issues arrays. This broke the dashboard charts for error/warning icons and participant counts. Adds lightweight annotations via Exists() subqueries and Count() so the list includes: - has_errors (boolean) - has_warnings (boolean) - participants_count (integer) No N+1 queries — all computed in the same SQL query. * fix: use Subquery for participants_count to avoid filtered join bug Count('participants') reuses the filtered JOIN when participantId is in the query string, returning 1 instead of the real total. Switched to a Subquery that counts independently of the request's participant filter. Addresses review feedback from Codex and Alberto. * fix: exclude soft-deleted participants from participants_count The Subquery used Participant.objects.filter() which bypasses the is_active=True check, overcounting if any participants were soft-deleted.
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17
Summary
A) Remove expand_fields from conference list
GET /conferences?appId=...) no longer inlinesparticipantsandissuesGET /conferences/<id>) still returns themB) Server-side pagination (opt-in, backward compatible)
?limit=and?offset=params{ "results": [...], "count": 1234 }{ "data": [...] }— no breaking changeC) Fix BaseModel.filter() eager materialization
.exists()call (result was discarded — wasted query)for obj in filtered: obj.prepare()loop that loaded ALL rows into memoryfilter()now returns a lazy QuerySet soLIMIT/OFFSETtranslates to SQLprepare()moved intoserialize()loop to preserveApp.prepare()behaviorTest results (local, 2079 conferences)
{ data: [...] }?limit=3&offset=0→{ results, count }?limit=3&offset=3→ page 2limit=0/limit=-1→ clamped to 1limit=abc→ 400 errorlimit=500→ clamped to 200Files changed
app/models/basemodel.pyfilter()app/utils.pyprepare()in serialize loop +paginate_and_serialize()helperapp/views/conference_view.pyapp/views/session_view.pyapp/views/participant_view.pyapp/views/event_view.pyapp/views/conference_events_view.py