From fdf6401141e8e2104c3d79d8f87ee3a0c857d97b Mon Sep 17 00:00:00 2001 From: Tanner Prestegard <tanner.prestegard@ligo.org> Date: Fri, 22 Jun 2018 09:04:37 -0500 Subject: [PATCH] Created CommaSeparatedOrList field New CommaSeparatedOrListField type which accepts a comma-separated string (and splits it into a list) or a list input. Useful for handling input from the web interface as well as from the Python client in either form. --- gracedb/superevents/api/fields.py | 27 ++++++++++++++++++++++++++ gracedb/superevents/api/serializers.py | 17 ++++++++-------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/gracedb/superevents/api/fields.py b/gracedb/superevents/api/fields.py index 6b7469aed..f2a4b7f1d 100644 --- a/gracedb/superevents/api/fields.py +++ b/gracedb/superevents/api/fields.py @@ -1,5 +1,10 @@ from rest_framework import fields +import six +import logging +logger = logging.getLogger(__name__) + + class CustomHiddenDefault(fields.CurrentUserDefault): context_key = None @@ -37,3 +42,25 @@ class ParentObjectDefault(CustomHiddenDefault): value = value() #value = serializer_field.context['view'].get_parent() return value + + +class CommaSeparatedOrListField(fields.ListField): + default_style = {'base_template': 'input.html'} + + def __init__(self, *args, **kwargs): + super(CommaSeparatedOrListField, self).__init__(*args, **kwargs) + # Set form style for browsable API + self.style = kwargs.get('style', self.default_style) + + def to_internal_value(self, data): + # Empirical tests with HTML forms indicate that if we enter + # something like 1,2,3 in a form, we will get something like + # [u'1,2,3'] here. So if we get input like that, we convert it + # to [u'1', u'2', u'3'], then pass it to the base class's + # to_internal_value() method. Might not be safe for cases where + # a list contains CharFields which might have commas in them. + if (isinstance(data, list) and len(data) == 1 and + isinstance(data[0], six.string_types)): + data = data[0].split(',') + return super(CommaSeparatedOrListField, self).to_internal_value(data) + diff --git a/gracedb/superevents/api/serializers.py b/gracedb/superevents/api/serializers.py index 5fc630a74..acac88e09 100644 --- a/gracedb/superevents/api/serializers.py +++ b/gracedb/superevents/api/serializers.py @@ -5,7 +5,7 @@ from django.conf import settings from ..models import Superevent, Labelling, Log, VOEvent, EMObservation, \ EMFootprint -from .fields import ParentObjectDefault +from .fields import ParentObjectDefault, CommaSeparatedOrListField from .settings import SUPEREVENT_LOOKUP_FIELD from events.models import Event, Label, Tag, EMGroup @@ -14,6 +14,7 @@ from events.api.fields import EventGraceidField UserModel = get_user_model() +import os import functools import logging logger = logging.getLogger(__name__) @@ -448,17 +449,17 @@ class SupereventEMObservationSerializer(serializers.ModelSerializer): default=serializers.CurrentUserDefault()) superevent = serializers.HiddenField(write_only=True, default=ParentObjectDefault(context_key='superevent')) - ra_list = serializers.ListField(child=serializers.FloatField(), + ra_list = CommaSeparatedOrListField(child=serializers.FloatField(), write_only=True) - dec_list = serializers.ListField(child=serializers.FloatField(), + dec_list = CommaSeparatedOrListField(child=serializers.FloatField(), write_only=True) - ra_width_list = serializers.ListField(child=serializers.FloatField(), + ra_width_list = CommaSeparatedOrListField(child=serializers.FloatField(), write_only=True) - dec_width_list = serializers.ListField(child=serializers.FloatField(), + dec_width_list = CommaSeparatedOrListField(child=serializers.FloatField(), write_only=True) - start_time_list = serializers.ListField(child=serializers.DateTimeField(), - write_only=True) - duration_list = serializers.ListField( + start_time_list = CommaSeparatedOrListField( + child=serializers.DateTimeField(), write_only=True) + duration_list = CommaSeparatedOrListField( child=serializers.IntegerField(min_value=0), write_only=True) class Meta: -- GitLab