Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions app/models/basemodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,19 +153,15 @@ def get_or_create(cls, *args, **kwargs):
def filter(cls, *args, **kwargs):
"""
Wrapper over the standard filter method that adds the is_active flag.
Returns a lazy QuerySet so that pagination (LIMIT/OFFSET) is applied
at the database level rather than in Python.

:param args: the anonymous query criteria
:param kwargs: the named (key word) query criteria
:return the filtered QuerySet object
"""
kwargs['is_active'] = True
filtered = cls.objects.filter(*args, **kwargs).order_by('created_at')
filtered.exists()

for obj in filtered:
obj.prepare()

return filtered
return cls.objects.filter(*args, **kwargs).order_by('created_at')

def prepare(self):
"""
Expand Down
31 changes: 30 additions & 1 deletion app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ def serialize(
final_alias_list.update(alias_list)

for obj in objs:
if hasattr(obj, 'prepare'):
obj.prepare()
d = {}
for field in obj._meta.get_fields():
key = field.name
Expand Down Expand Up @@ -344,4 +346,31 @@ def build_conference_summary(conference):
pass

def clamp(n, smallest, largest):
return max(smallest, min(n, largest))
return max(smallest, min(n, largest))


def paginate_and_serialize(request, queryset, default_limit=50, max_limit=200, **serialize_kwargs):
"""
Adds opt-in server-side pagination to list endpoints.
If ?limit= or ?offset= is present, returns { results: [...], count: N }.
Otherwise returns the original { data: [...] } format for backward compatibility.
"""
limit_param = request.GET.get('limit')
offset_param = request.GET.get('offset')

if limit_param is not None or offset_param is not None:
try:
limit = clamp(int(limit_param or default_limit), 1, max_limit)
offset = max(0, int(offset_param or 0))
except (ValueError, TypeError):
from .errors import INVALID_PARAMETERS
raise PMError(status=400, app_error=INVALID_PARAMETERS)

count = queryset.count()
page = queryset[offset:offset + limit]
return {
'results': serialize(page, **serialize_kwargs)['data'],
'count': count,
}
else:
return serialize(queryset, **serialize_kwargs)
2 changes: 1 addition & 1 deletion app/views/conference_events_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ def get(cls, request, pk=None):
except Conference.DoesNotExist:
raise PMError(status=400, app_error=CONFERENCE_NOT_FOUND)

return EventView.retrieve_events(event_type=request.GET.get('type'), conference=conference)
return EventView.retrieve_events(request, event_type=request.GET.get('type'), conference=conference)
7 changes: 2 additions & 5 deletions app/views/conference_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from ..errors import (INVALID_PARAMETERS, CONFERENCE_NOT_FOUND,
MISSING_PARAMETERS, PMError)
from ..utils import JSONHttpResponse, serialize
from ..utils import JSONHttpResponse, serialize, paginate_and_serialize
from ..models.conference import Conference
from .generic_view import GenericView

Expand Down Expand Up @@ -45,10 +45,7 @@ def filter(cls, request):
raise PMError(status=400, app_error=INVALID_PARAMETERS)

return JSONHttpResponse(
content=serialize(
objs=objs,
expand_fields=('participants', 'issues'),
),
content=paginate_and_serialize(request, objs),
)

@classmethod
Expand Down
7 changes: 4 additions & 3 deletions app/views/event_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from ..models.connection import Connection
from ..models.generic_event import GenericEvent
from ..models.participant import Participant
from ..utils import JSONHttpResponse, serialize, validate_string, validate_positive_number
from ..utils import JSONHttpResponse, serialize, paginate_and_serialize, validate_string, validate_positive_number


class EventView(GenericView):
Expand Down Expand Up @@ -52,12 +52,12 @@ def query_events(event_type=None, conference=None, participant=None, filters=Non
raise PMError(status=400, app_error=INVALID_PARAMETERS)

@staticmethod
def retrieve_events(event_type=None, conference=None, participant=None, filters=None):
def retrieve_events(request, event_type=None, conference=None, participant=None, filters=None):
"""Used to return a JSON response of a specific event query"""

objs = EventView.query_events(event_type, conference, participant, filters)

return JSONHttpResponse(content=serialize(objs))
return JSONHttpResponse(content=paginate_and_serialize(request, objs))

@classmethod
def get(cls, request):
Expand Down Expand Up @@ -97,6 +97,7 @@ def get(cls, request):
filters[key] = request.GET.get(rkey)

return cls.retrieve_events(
request,
event_type=request.GET.get('type'),
conference=conference,
participant=participant,
Expand Down
6 changes: 2 additions & 4 deletions app/views/participant_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from ..errors import (INVALID_PARAMETERS, PARTICIPANT_NOT_FOUND,
MISSING_PARAMETERS, PMError)
from ..utils import JSONHttpResponse, serialize
from ..utils import JSONHttpResponse, serialize, paginate_and_serialize
from ..models.participant import Participant
from .generic_view import GenericView

Expand Down Expand Up @@ -43,9 +43,7 @@ def filter(cls, request):
raise PMError(status=400, app_error=INVALID_PARAMETERS)

return JSONHttpResponse(
content=serialize(
objs=objs,
),
content=paginate_and_serialize(request, objs),
)

@classmethod
Expand Down
6 changes: 3 additions & 3 deletions app/views/session_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ..models.participant import Participant
from ..models.session import Session
from ..utils import (JSONHttpResponse, generate_session_token, get_client_ip, get_geoip_data,
serialize, validate_string, validate_meta, validate_positive_number)
serialize, paginate_and_serialize, validate_string, validate_meta, validate_positive_number)
from .generic_view import GenericView


Expand Down Expand Up @@ -75,8 +75,8 @@ def get(cls, request):
if objs is not None:
return JSONHttpResponse(
status=200,
content=serialize(
objs,
content=paginate_and_serialize(
request, objs,
blacklist=('constraints',),
expand_fields=('issues',),
)
Expand Down