From d600a3d239a8442002d83b777448c4e733333996 Mon Sep 17 00:00:00 2001 From: Tanner Prestegard <tanner.prestegard@ligo.org> Date: Fri, 25 May 2018 10:42:34 -0500 Subject: [PATCH] adding search filter and ordering filter to superevents api --- gracedb/superevents/api/filters.py | 79 ++++++++++++++++++++++++++++++ gracedb/superevents/api/views.py | 6 ++- 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 gracedb/superevents/api/filters.py diff --git a/gracedb/superevents/api/filters.py b/gracedb/superevents/api/filters.py new file mode 100644 index 000000000..185354ecc --- /dev/null +++ b/gracedb/superevents/api/filters.py @@ -0,0 +1,79 @@ +from rest_framework import filters, exceptions + +from django.http import HttpResponseBadRequest + +from ..query import parseSupereventQuery + +from pyparsing import ParseException +import logging +logger = logging.getLogger(__name__) + +class SupereventSearchFilter(filters.SearchFilter): + search_param = 'query' + + def get_search_terms(self, request): + # Custom because we don't want default behavior of splitting on spaces + return request.query_params.get(self.search_param, '') + + def filter_queryset(self, request, queryset, view): + query = self.get_search_terms(request) + + if not query: + return queryset + + # Do filtering + try: + filter_params = parseSupereventQuery(query) + except ParseException as e: + raise exceptions.ParseError('Invalid query') + + return queryset.filter(filter_params) + + +class SupereventOrderingFilter(filters.OrderingFilter): + ordering_param = 'sort' + field_map = { + 'created': u'date_created', + 'preferred_event': u'preferred_event__id', + 'id': [u't_0_date', u'is_gw', u'gw_date_number', 'base_date_number'], + 'superevent_id': [u't_0_date', u'is_gw', u'gw_date_number', + 'base_date_number'], + } + + def custom_field_mapping(self, fields): + out_fields = [] + for f in fields: + prefix = '-' if f.startswith('-') else '' + f_s = f.lstrip('-') + if f_s in self.field_map.keys(): + mapped_fields = self.field_map[f_s] + if not isinstance(mapped_fields, list): + mapped_fields = [mapped_fields] + if prefix: + mapped_fields = [prefix + f for f in mapped_fields] + out_fields.extend(mapped_fields) + else: + out_fields.append(f) + return out_fields + + def get_ordering(self, request, queryset, view): + """ + Same as base class get_ordering method except we add in custom + mappings between ordering keywords and fields. + """ + # Get ordering fields from request query params + params = request.query_params.get(self.ordering_param) + if params: + fields = [param.strip() for param in params.split(',')] + + # Get custom field mappings + fields = self.custom_field_mapping(fields) + + # Remove invalid fields + ordering = self.remove_invalid_fields(queryset, fields, view, + request) + if ordering: + return ordering + + # No ordering was included, or all the ordering fields were invalid + return self.get_default_ordering(view) diff --git a/gracedb/superevents/api/views.py b/gracedb/superevents/api/views.py index 5d094b24c..094d63fce 100644 --- a/gracedb/superevents/api/views.py +++ b/gracedb/superevents/api/views.py @@ -22,6 +22,7 @@ from events.view_utils import reverse as gracedb_reverse #from events.api.views import IsAuthorizedForPipeline, LigoLwRenderer from events.api.backends import LigoAuthentication +from .filters import SupereventSearchFilter, SupereventOrderingFilter from .mixins import GetParentSupereventMixin, BaseGetObjectMixin from .paginators import BasePaginationFactory, CustomLabelPagination, \ CustomLogTagPagination, CustomSupereventPagination @@ -29,7 +30,6 @@ from .serializers import SupereventSerializer, SupereventUpdateSerializer, \ SupereventEventSerializer, SupereventLabelSerializer, \ SupereventLogSerializer, SupereventLogTagSerializer, \ SupereventVOEventSerializer, SupereventEMObservationSerializer - from .settings import SUPEREVENT_LOOKUP_FIELD, SUPEREVENT_LOOKUP_REGEX import os @@ -47,6 +47,10 @@ class SupereventViewSet(viewsets.ModelViewSet): pagination_class = CustomSupereventPagination lookup_field = SUPEREVENT_LOOKUP_FIELD lookup_value_regex = SUPEREVENT_LOOKUP_REGEX + filter_backends = (SupereventSearchFilter, SupereventOrderingFilter,) + ordering_fields = ('date_created', 't_0', 't_start', 't_end', + 'preferred_event__id', 't_0_date', 'is_gw', 'base_date_number', + 'gw_date_number') def get_serializer_class(self): """Select a different serializer for updates""" -- GitLab