class TimelineSerializer(serializers.Serializer): INTERVAL_CHOICES = ('hour', 'day', 'week', 'month') start_time = TimestampField(default=lambda: core_utils.timeshift(days=-1)) end_time = TimestampField(default=lambda: core_utils.timeshift()) interval = serializers.ChoiceField(choices=INTERVAL_CHOICES, default='day') def get_date_points(self): start_time = self.validated_data['start_time'] end_time = self.validated_data['end_time'] interval = self.validated_data['interval'] if interval == 'hour': start_point = start_time.replace(second=0, minute=0, microsecond=0) interval = timedelta(hours=1) elif interval == 'day': start_point = start_time.replace(hour=0, second=0, minute=0, microsecond=0) interval = timedelta(days=1) elif interval == 'week': start_point = start_time.replace(hour=0, second=0, minute=0, microsecond=0) interval = timedelta(days=7) elif interval == 'month': start_point = start_time.replace(hour=0, second=0, minute=0, microsecond=0) interval = timedelta(days=30) points = [start_time] current_point = start_point while current_point <= end_time: points.append(current_point) current_point += interval if points[-1] != end_time: points.append(end_time) return [p for p in points if start_time <= p <= end_time]
class HistorySerializer(serializers.Serializer): """ Receive datetime as timestamps and converts them to list of datetimes Support 2 types of input data: - start, end and points_count - interval from <start> to <end> will be automatically split into <points_count> pieces - point_list - list of timestamps that will be converted to datetime points """ start = TimestampField(required=False) end = TimestampField(required=False) points_count = serializers.IntegerField(min_value=2, required=False) point_list = serializers.ListField(child=TimestampField(), required=False) def validate(self, attrs): autosplit_fields = {'start', 'end', 'points_count'} if ( 'point_list' not in attrs or not attrs['point_list'] ) and not autosplit_fields == set(attrs.keys()): raise serializers.ValidationError( _( 'Not enough parameters for historical data. ' '(Either "point" or "start" + "end" + "points_count" parameters have to be provided).' ) ) if 'point_list' in attrs and autosplit_fields & set(attrs.keys()): raise serializers.ValidationError( _( 'Too many parameters for historical data. ' '(Either "point" or "start" + "end" + "points_count" parameters have to be provided).' ) ) if 'point_list' not in attrs and not attrs['start'] < attrs['end']: raise serializers.ValidationError( _('Start timestamps have to be later than end timestamps.') ) return attrs # History serializer is used for validation only. We are providing custom method for such serializers # to avoid confusion with to_internal_value or to_representation DRF methods. def get_filter_data(self): if 'point_list' in self.validated_data: return self.validated_data['point_list'] else: interval = (self.validated_data['end'] - self.validated_data['start']) / ( self.validated_data['points_count'] - 1 ) return [ self.validated_data['start'] + interval * i for i in range(self.validated_data['points_count']) ]
class TimestampIntervalSerializer(serializers.Serializer): start = TimestampField(required=False) end = TimestampField(required=False) def validate(self, data): """ Check that the start is before the end. """ if 'start' in data and 'end' in data and data['start'] >= data['end']: raise serializers.ValidationError(_('End must occur after start.')) return data # TimeInterval serializer is used for validation only. We are providing custom method for such serializers # to avoid confusion with to_internal_value or to_representation DRF methods. def get_filter_data(self): """ Return start and end as datetime """ return self.validated_data
class TimestampSerializer(serializers.Serializer): content = TimestampField()