diff --git a/gracedb/superevents/api/mixins.py b/gracedb/superevents/api/mixins.py index e3b5d585f5e520488dacc05a331b6d4f96698d80..fa3417d7546b34be0cf8572a61b71260ef1ebdc8 100644 --- a/gracedb/superevents/api/mixins.py +++ b/gracedb/superevents/api/mixins.py @@ -35,22 +35,6 @@ class GetParentSupereventMixin(GetParentMixin): return Superevent.get_filter_kwargs_for_date_id_lookup(superevent_id) -class BaseGetObjectMixin(object): - query_field = None - - def __init__(self, *args, **kwargs): - super(BaseGetObjectMixin, self).__init__(*args, **kwargs) - if self.query_field is None: - self.query_field = self.lookup_field - - def get_object(self): - # TODO: do we need some kind of permissions check in here somewhere? - queryset = self.filter_queryset(self.get_queryset()) - query_value = self.kwargs.get(self.lookup_field) - filter_kwargs = {self.query_field: query_value} - obj = get_object_or_404(queryset, **filter_kwargs) - return obj - class SafeDestroyMixin(mixins.DestroyModelMixin): """ diff --git a/gracedb/superevents/api/serializers.py b/gracedb/superevents/api/serializers.py index 78ff2b9417e130261d336e9c5390f3f07b7db8cb..9c8c66398b2052d3e3d62530afb8b0669bde1516 100644 --- a/gracedb/superevents/api/serializers.py +++ b/gracedb/superevents/api/serializers.py @@ -8,7 +8,7 @@ from ..models import Superevent, Labelling, Log, VOEvent, EMObservation, \ from .fields import ParentObjectDefault, CommaSeparatedOrListField, \ ChoiceDisplayField -from .settings import SUPEREVENT_LOOKUP_FIELD +from .settings import SUPEREVENT_LOOKUP_URL_KWARG from events.models import Event, Label, Tag, EMGroup from events.view_utils import reverse as gracedb_reverse @@ -389,7 +389,7 @@ class SupereventLogTagSerializer(serializers.ModelSerializer): def get_self(self, obj): superevent_id = self.context['view'].kwargs.get( - SUPEREVENT_LOOKUP_FIELD) + SUPEREVENT_LOOKUP_URL_KWARG) log_N = self.context['view'].kwargs.get('N') return gracedb_reverse('superevents:superevent-log-tag-detail', args=[superevent_id, log_N, obj.name], diff --git a/gracedb/superevents/api/settings.py b/gracedb/superevents/api/settings.py index 34a5e082f613c6b4eace87880c535b4e6049554f..277c5e7e2cd88348f8b2bf53f3e110782db74c03 100644 --- a/gracedb/superevents/api/settings.py +++ b/gracedb/superevents/api/settings.py @@ -1,5 +1,5 @@ from ..models import Superevent -SUPEREVENT_LOOKUP_FIELD = 'superevent_id' +SUPEREVENT_LOOKUP_URL_KWARG = 'superevent_id' SUPEREVENT_LOOKUP_REGEX = Superevent.ID_REGEX diff --git a/gracedb/superevents/api/urls.py b/gracedb/superevents/api/urls.py index b914b5c68016c9da4e1004e25f3090569fa4b47a..541ad5776aa65554f439e828b4f1fa4cca723296 100644 --- a/gracedb/superevents/api/urls.py +++ b/gracedb/superevents/api/urls.py @@ -4,8 +4,8 @@ from .views import * from .settings import SUPEREVENT_LOOKUP_REGEX # URL kwarg for superevent detail and nested pages -SUPEREVENT_DETAIL_ROOT = '(?P<{lookup_field}>{regex})'.format( - lookup_field=SupereventViewSet.lookup_field, +SUPEREVENT_DETAIL_ROOT = '(?P<{lookup_url_kwarg}>{regex})'.format( + lookup_url_kwarg=SupereventViewSet.lookup_url_kwarg, regex=SUPEREVENT_LOOKUP_REGEX) # URLs which are nested below a single superevent detail @@ -18,39 +18,40 @@ suburlpatterns = [ url(r'^confirm_as_gw/$', SupereventViewSet.as_view( {'post': 'confirm_as_gw'}), name='superevent-confirm-as-gw'), - # Event list and create (add event to superevent) + # Event list and creation (addition to superevent) url(r'^events/$', SupereventEventViewSet.as_view({'get': 'list', 'post': 'create'}), name='superevent-event-list'), # Event detail and delete (remove from superevent) - url(r'^events/(?P<{lookup_field}>[GEHMT]\d+)/$'.format(lookup_field= - SupereventEventViewSet.lookup_field), SupereventEventViewSet.as_view({ - 'get': 'retrieve', 'delete': 'destroy'}), - name='superevent-event-detail'), + url(r'^events/(?P<{lookup_url_kwarg}>[GEHMT]\d+)/$'.format( + lookup_url_kwarg=SupereventEventViewSet.lookup_url_kwarg), + SupereventEventViewSet.as_view({'get': 'retrieve', + 'delete': 'destroy'}), name='superevent-event-detail'), - # Labelling list/create + # Labelling list and creation url(r'^labels/$', SupereventLabelViewSet.as_view({'get': 'list', 'post': 'create'}), name='superevent-label-list'), - # Labelling detail/delete - url(r'^labels/(?P<{lookup_field}>.+)/$'.format(lookup_field= - SupereventLabelViewSet.lookup_field), SupereventLabelViewSet.as_view({ - 'get': 'retrieve', 'delete': 'destroy'}), - name='superevent-label-detail'), + # Labelling detail and deletion + url(r'^labels/(?P<{lookup_url_kwarg}>.+)/$'.format(lookup_url_kwarg= + SupereventLabelViewSet.lookup_url_kwarg), + SupereventLabelViewSet.as_view({'get': 'retrieve', + 'delete': 'destroy'}), name='superevent-label-detail'), - # Log list/create + # Log list and creation url(r'^logs/$', SupereventLogViewSet.as_view({'get': 'list', 'post': 'create'}), name='superevent-log-list'), # Log detail - url(r'^logs/(?P<{lookup_field}>\d+)/$'.format(lookup_field= - SupereventLogViewSet.lookup_field), SupereventLogViewSet.as_view({ + url(r'^logs/(?P<{lookup_url_kwarg}>\d+)/$'.format(lookup_url_kwarg= + SupereventLogViewSet.lookup_url_kwarg), SupereventLogViewSet.as_view({ 'get': 'retrieve'}), name='superevent-log-detail'), - # Tag list (for log) and create - url(r'^logs/(?P<{lookup_field}>\d+)/tags/$'.format(lookup_field= - SupereventLogViewSet.lookup_field), SupereventLogTagViewSet.as_view({ - 'get': 'list', 'post': 'create'}), name='superevent-log-tag-list'), - # Tag detail/delete + # Tag list (for log) and creation (addition of tag to log) + url(r'^logs/(?P<{lookup_url_kwarg}>\d+)/tags/$'.format( + lookup_url_kwarg=SupereventLogViewSet.lookup_url_kwarg), + SupereventLogTagViewSet.as_view({'get': 'list', 'post': 'create'}), + name='superevent-log-tag-list'), + # Tag detail and deletion (removal of tag from log) url(r'^logs/(?P<{log_lookup}>\d+)/tags/(?P<{tag_lookup}>.+)/$'.format( - log_lookup=SupereventLogViewSet.lookup_field, tag_lookup= - SupereventLogTagViewSet.lookup_field), + log_lookup=SupereventLogViewSet.lookup_url_kwarg, tag_lookup= + SupereventLogTagViewSet.lookup_url_kwarg), SupereventLogTagViewSet.as_view({'get': 'retrieve', 'delete': 'destroy'}), name='superevent-log-tag-detail'), @@ -58,28 +59,28 @@ suburlpatterns = [ url(r'^files/$', SupereventFileViewSet.as_view({'get': 'list',}), name='superevent-file-list'), # File detail (download) - url(r'^files/(?P<{lookup_field}>.+)$'.format(lookup_field= - SupereventFileViewSet.lookup_field), SupereventFileViewSet.as_view({ - 'get': 'retrieve'}), name='superevent-file-detail'), + url(r'^files/(?P<{lookup_url_kwarg}>.+)$'.format(lookup_url_kwarg= + SupereventFileViewSet.lookup_url_kwarg), SupereventFileViewSet.as_view( + {'get': 'retrieve'}), name='superevent-file-detail'), # Note: no option for POST since file uploads should be handled # by writing a log message - # VOEvent list/create + # VOEvent list and creation url(r'^voevents/$', SupereventVOEventViewSet.as_view({'get': 'list', 'post': 'create'}), name='superevent-voevent-list'), # VOEvent detail - url(r'^voevents/(?P<{lookup_field}>\d+)/$'.format(lookup_field= - SupereventVOEventViewSet.lookup_field), + url(r'^voevents/(?P<{lookup_url_kwarg}>\d+)/$'.format(lookup_url_kwarg= + SupereventVOEventViewSet.lookup_url_kwarg), SupereventVOEventViewSet.as_view({'get': 'retrieve'}), name='superevent-voevent-detail'), - # EMObservation list/create + # EMObservation list creation url(r'^emobservations/$', SupereventEMObservationViewSet.as_view( {'get': 'list', 'post': 'create'}), name='superevent-emobservation-list'), # EMObservation detail - url(r'^emobservations/(?P<{lookup_field}>\d+)/$'.format(lookup_field= - SupereventEMObservationViewSet.lookup_field), + url(r'^emobservations/(?P<{lookup_url_kwarg}>\d+)/$'.format( + lookup_url_kwarg=SupereventEMObservationViewSet.lookup_url_kwarg), SupereventEMObservationViewSet.as_view({'get': 'retrieve'}), name='superevent-emobservation-detail'), ] @@ -87,7 +88,7 @@ suburlpatterns = [ # Full urlpatterns urlpatterns = [ - # Superevent list and create + # Superevent list and creation url(r'^$', SupereventViewSet.as_view({'get': 'list', 'post': 'create'}), name='superevent-list'), diff --git a/gracedb/superevents/api/view_templates.py b/gracedb/superevents/api/view_templates.py index 2b3f5537c5c08bf9d66a4192fec984e66f48ad92..a070f926099091a9f453c7a82c01531169160ba8 100644 --- a/gracedb/superevents/api/view_templates.py +++ b/gracedb/superevents/api/view_templates.py @@ -7,50 +7,51 @@ from .views import SupereventViewSet, SupereventEventViewSet, \ # Placeholder parameters for getting URLs with reverse PH = { - SupereventViewSet.lookup_field: 'S800106a', # superevent_id - SupereventEventViewSet.lookup_field: 'G1234', # graceid - SupereventLabelViewSet.lookup_field: 'LABEL_NAME', # label name - SupereventLogViewSet.lookup_field: '3333', # log number (N) - SupereventLogTagViewSet.lookup_field: 'TAG_NAME', # tag name - SupereventFileViewSet.lookup_field: 'FILE_NAME', # file name - SupereventVOEventViewSet.lookup_field: '4444', # VOEvent number (N) - SupereventEMObservationViewSet.lookup_field: '5555', # EMObservation number (N) + SupereventViewSet.lookup_url_kwarg: 'S800106a', # superevent_id + SupereventEventViewSet.lookup_url_kwarg: 'G1234', # graceid + SupereventLabelViewSet.lookup_url_kwarg: 'LABEL_NAME', # label name + SupereventLogViewSet.lookup_url_kwarg: '3333', # log number (N) + SupereventLogTagViewSet.lookup_url_kwarg: 'TAG_NAME', # tag name + SupereventFileViewSet.lookup_url_kwarg: 'FILE_NAME', # file name + SupereventVOEventViewSet.lookup_url_kwarg: '4444', # VOEvent number (N) + SupereventEMObservationViewSet.lookup_url_kwarg: '5555', # EMObservation + # number (N) } def construct_api_url_templates(request=None): # Bind our custom reverse for ease of use sr = lambda view_name, args=[]: reverse('superevents:' + view_name, args=[ - PH[SupereventViewSet.lookup_field]] + args, request=request) + PH[SupereventViewSet.lookup_url_kwarg]] + args, request=request) # Dict of views and temporary arguments which will be passed to reverse views = { 'superevent-detail': [], 'superevent-event-list': [], - 'superevent-event-detail': [PH[SupereventEventViewSet.lookup_field]], + 'superevent-event-detail': [PH[SupereventEventViewSet.lookup_url_kwarg]], 'superevent-label-list': [], - 'superevent-label-detail': [PH[SupereventLabelViewSet.lookup_field]], + 'superevent-label-detail': [PH[SupereventLabelViewSet.lookup_url_kwarg]], 'superevent-log-list': [], - 'superevent-log-detail': [PH[SupereventLogViewSet.lookup_field]], - 'superevent-log-tag-list': [PH[SupereventLogViewSet.lookup_field]], - 'superevent-log-tag-detail': [PH[SupereventLogViewSet.lookup_field], - PH[SupereventLogTagViewSet.lookup_field]], + 'superevent-log-detail': [PH[SupereventLogViewSet.lookup_url_kwarg]], + 'superevent-log-tag-list': [PH[SupereventLogViewSet.lookup_url_kwarg]], + 'superevent-log-tag-detail': [PH[SupereventLogViewSet.lookup_url_kwarg], + PH[SupereventLogTagViewSet.lookup_url_kwarg]], 'superevent-file-list': [], - 'superevent-file-detail': [PH[SupereventFileViewSet.lookup_field]], + 'superevent-file-detail': [PH[SupereventFileViewSet.lookup_url_kwarg]], 'superevent-voevent-list': [], 'superevent-voevent-detail': [ - PH[SupereventVOEventViewSet.lookup_field]], + PH[SupereventVOEventViewSet.lookup_url_kwarg]], 'superevent-emobservation-list': [], 'superevent-emobservation-detail': [ - PH[SupereventEMObservationViewSet.lookup_field]], + PH[SupereventEMObservationViewSet.lookup_url_kwarg]], 'superevent-confirm-as-gw': [] } # Dict of URL templates: - # keys are view_name + '-template' + # keys are like '{view_name}-template' # values are URLs with placeholder parameters - templates = {view + '-template': sr(view, args=args) - for view, args in views.iteritems()} + templates = {view_name + '-template': sr(view_name, args=args) + for view_name, args in views.iteritems()} # Replace URL placeholder parameters with string formatting placeholders # Ex: replace 'G1234' with '{graceid}' diff --git a/gracedb/superevents/api/views.py b/gracedb/superevents/api/views.py index 830d34d795d766ba5de46d03318435158c3d115e..613d79966afcbf04d442bcb82eea61328407739d 100644 --- a/gracedb/superevents/api/views.py +++ b/gracedb/superevents/api/views.py @@ -28,15 +28,15 @@ from events.api.backends import LigoAuthentication from ..buildVOEvent import VOEventBuilderException from .filters import SupereventSearchFilter, SupereventOrderingFilter, \ DjangoObjectAndGlobalPermissionsFilter -from .mixins import GetParentSupereventMixin, BaseGetObjectMixin, \ - SafeDestroyMixin, SafeCreateMixin +from .mixins import GetParentSupereventMixin, SafeCreateMixin, \ + SafeDestroyMixin from .paginators import BasePaginationFactory, CustomLabelPagination, \ CustomLogTagPagination, CustomSupereventPagination from .serializers import SupereventSerializer, SupereventUpdateSerializer, \ SupereventEventSerializer, SupereventLabelSerializer, \ SupereventLogSerializer, SupereventLogTagSerializer, \ SupereventVOEventSerializer, SupereventEMObservationSerializer -from .settings import SUPEREVENT_LOOKUP_FIELD, SUPEREVENT_LOOKUP_REGEX +from .settings import SUPEREVENT_LOOKUP_URL_KWARG, SUPEREVENT_LOOKUP_REGEX import os import logging @@ -51,7 +51,7 @@ class SupereventViewSet(SafeCreateMixin, viewsets.ModelViewSet): queryset = Superevent.objects.all() serializer_class = SupereventSerializer pagination_class = CustomSupereventPagination - lookup_field = SUPEREVENT_LOOKUP_FIELD + lookup_url_kwarg = SUPEREVENT_LOOKUP_URL_KWARG lookup_value_regex = SUPEREVENT_LOOKUP_REGEX filter_backends = (DjangoObjectAndGlobalPermissionsFilter, SupereventSearchFilter, SupereventOrderingFilter,) @@ -68,7 +68,7 @@ class SupereventViewSet(SafeCreateMixin, viewsets.ModelViewSet): def get_object(self): queryset = self.filter_queryset(self.get_queryset()) - superevent_id = self.kwargs.get(self.lookup_field) + superevent_id = self.kwargs.get(self.lookup_url_kwarg) obj = get_superevent_by_date_id_or_404(self.request, superevent_id) @@ -105,7 +105,7 @@ class SupereventEventViewSet(mixins.ListModelMixin, """View for events attached to a superevent""" serializer_class = SupereventEventSerializer pagination_class = BasePaginationFactory(results_name='events') - lookup_field = 'graceid' + lookup_url_kwarg = 'graceid' destroy_error_classes = (Superevent.PreferredEventRemovalError,) destroy_error_response_status = status.HTTP_400_BAD_REQUEST @@ -117,7 +117,7 @@ class SupereventEventViewSet(mixins.ListModelMixin, def get_object(self): queryset = self.filter_queryset(self.get_queryset()) - graceid = self.kwargs.get(self.lookup_field) + graceid = self.kwargs.get(self.lookup_url_kwarg) filter_kwargs = {'id': int(graceid[1:])} obj = get_object_or_404(queryset, **filter_kwargs) @@ -134,13 +134,12 @@ class SupereventEventViewSet(mixins.ListModelMixin, class SupereventLabelViewSet(GetParentSupereventMixin, - BaseGetObjectMixin, viewsets.ModelViewSet): """Superevent labels""" serializer_class = SupereventLabelSerializer pagination_class = CustomLabelPagination - lookup_field = 'label_name' - query_field = 'label__name' + lookup_url_kwarg = 'label_name' + lookup_field = 'label__name' def get_queryset(self): superevent = self.get_parent() @@ -157,7 +156,6 @@ class SupereventLogViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, SafeCreateMixin, GetParentSupereventMixin, - BaseGetObjectMixin, viewsets.GenericViewSet): """ View for log messages attached to a superevent. @@ -166,6 +164,7 @@ class SupereventLogViewSet(mixins.ListModelMixin, serializer_class = SupereventLogSerializer pagination_class = BasePaginationFactory(results_name='log') filter_backends = (DjangoObjectAndGlobalPermissionsFilter,) + lookup_url_kwarg = 'N' lookup_field = 'N' def get_queryset(self): @@ -176,7 +175,6 @@ class SupereventLogViewSet(mixins.ListModelMixin, class SupereventLogTagViewSet(GetParentSupereventMixin, - BaseGetObjectMixin, viewsets.ModelViewSet, SafeCreateMixin): """ @@ -184,8 +182,8 @@ class SupereventLogTagViewSet(GetParentSupereventMixin, """ serializer_class = SupereventLogTagSerializer pagination_class = CustomLogTagPagination - lookup_field = 'tag_name' - query_field = 'name' + lookup_url_kwarg = 'tag_name' + lookup_field = 'name' def get_parent_log(self): # TODO: check superevent permissions here @@ -207,7 +205,7 @@ class SupereventLogTagViewSet(GetParentSupereventMixin, class SupereventFileViewSet(GetParentSupereventMixin, viewsets.ViewSet): """Superevent files""" - lookup_field = 'file_name' + lookup_url_kwarg = 'file_name' def list(self, request, *args, **kwargs): parent_superevent = self.get_parent() @@ -230,15 +228,15 @@ class SupereventVOEventViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, SafeCreateMixin, GetParentSupereventMixin, - BaseGetObjectMixin, viewsets.GenericViewSet): """ View for VOEvents attached to a superevent. """ serializer_class = SupereventVOEventSerializer pagination_class = BasePaginationFactory(results_name='voevents') - lookup_field = 'N' create_error_classes = (VOEventBuilderException) + lookup_url_kwarg = 'N' + lookup_field = 'N' def get_queryset(self): superevent = self.get_parent() @@ -257,6 +255,7 @@ class SupereventEMObservationViewSet(mixins.ListModelMixin, """ serializer_class = SupereventEMObservationSerializer pagination_class = BasePaginationFactory(results_name='observations') + lookup_url_kwarg = 'N' lookup_field = 'N' def get_queryset(self):