def test_get_form_submissions_two_xforms(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() self._publish_xls_file(os.path.join("fixtures", "gps", "gps.xls")) first_xform = self.xform self.xform = self.user.xforms.all().order_by('-pk')[0] self._make_submission( os.path.join('onadata', 'apps', 'main', 'tests', 'fixtures', 'gps', 'instances', 'gps_1980-01-23_20-52-08.xml')) count_key = 'count' fields = ['_submission_time', '_xform_id_string'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[count_key], count) count = len(first_xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(first_xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[count_key], count)
def test_get_form_submissions_two_xforms(self, mock_time): mock_time.return_value = datetime.now() self._make_submissions() self._publish_xls_file(os.path.join( "fixtures", "gps", "gps.xls")) first_xform = self.xform self.xform = self.user.xforms.all().order_by('-pk')[0] self._make_submission(os.path.join( 'onadata', 'apps', 'main', 'tests', 'fixtures', 'gps', 'instances', 'gps_1980-01-23_20-52-08.xml')) count_key = 'count' fields = ['_submission_time', '_xform_id_string'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field( self.xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count) count = len(first_xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field( first_xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_two_xforms(self, mock_time): mock_time.return_value = datetime.now() self._make_submissions() self._publish_xls_file(os.path.join("fixtures", "gps", "gps.xls")) first_xform = self.xform self.xform = self.user.xforms.all().order_by("-pk")[0] self._make_submission( os.path.join( "onadata", "apps", "main", "tests", "fixtures", "gps", "instances", "gps_1980-01-23_20-52-08.xml" ) ) count_key = "count" fields = ["_submission_time", "_xform_id_string"] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count) count = len(first_xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(first_xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def list(self, request, owner=None, formid=None, **kwargs): if owner is None and not request.user.is_anonymous(): owner = request.user.username data = [] if formid: xform = get_xform(formid, request) field = '_submission_time' name = 'date_of_submission' group = request.QUERY_PARAMS.get('group', None) alt_name = request.QUERY_PARAMS.get('name', None) if group: name = field = group if alt_name: name = alt_name try: data = get_form_submissions_grouped_by_field( xform, field, name) except ValueError as e: raise exceptions.ParseError(detail=e.message) else: data = self._get_formlist_data_points(request, owner) return Response(data)
def test_get_form_submissions_grouped_by_field_datetime_to_date( self, mock_time): now = datetime(2014, 1, 1, tzinfo=utc) times = [ now, now + timedelta(seconds=1), now + timedelta(seconds=2), now + timedelta(seconds=3) ] mock_time.side_effect = times self._make_submissions() for i in self.xform.instances.all().order_by('-pk'): i.date_created = times.pop() i.save() count_key = 'count' fields = ['_submission_time'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[field], str(now.date())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field_datetime_to_date( self, mock_time): now = datetime(2014, 1, 1) times = [ now, now + timedelta(seconds=1), now + timedelta(seconds=2), now + timedelta(seconds=3) ] mock_time.side_effect = times self._make_submissions() count_key = 'count' fields = ['_submission_time'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) expected_now = now.date() if not isinstance(result[field], date): expected_now = str(expected_now) self.assertEqual(result[field], expected_now) self.assertEqual(result[count_key], count)
def test_get_form_submissions_when_response_not_provided(self): """ Test that the None value is stripped when of the submissions doesnt have a response for the specified field """ self._make_submissions() count = Instance.objects.count() # make submission that doesnt have a response for # `available_transportation_types_to_referral_facility` path = os.path.join(self.this_directory, 'fixtures', 'transportation', 'instances', 'transport_no_response', 'transport_no_response.xml') self._make_submission(path, self.user.username) self.assertEqual(Instance.objects.count(), count + 1) field = 'transport/available_transportation_types_to_referral_facility' xform = self.user.xforms.all()[0] results = get_form_submissions_grouped_by_field( xform, field, 'available_transportation_types_to_referral_facility') # we should have a similar number of aggregates as submissions as each # submission has a unique value for the field self.assertEqual(len(results), count + 1) # the count where the value is None should have a count of 1 result = [ r for r in results if r['available_transportation_types_to_referral_facility'] is None ][0] self.assertEqual(result['count'], 1)
def to_native(self, obj): if obj is None: return \ super(SubmissionStatsInstanceSerializer, self).to_native(obj) request = self.context.get('request') field = request.QUERY_PARAMS.get('group') name = request.QUERY_PARAMS.get('name', field) if field is None: raise exceptions.ParseError(_(u"Expecting `group` and `name`" u" query parameters.")) try: data = get_form_submissions_grouped_by_field( obj, field, name) except ValueError as e: raise exceptions.ParseError(detail=e.message) else: if data: dd = obj.data_dictionary() element = dd.get_survey_element(field) if element and element.type in SELECT_FIELDS: for record in data: label = dd.get_choice_label(element, record[name]) record[name] = label return data
def test_get_form_submissions_when_response_not_provided(self): """ Test that the None value is stripped when of the submissions doesnt have a response for the specified field """ self._make_submissions() count = Instance.objects.count() # make submission that doesnt have a response for # `available_transportation_types_to_referral_facility` path = os.path.join( self.this_directory, 'fixtures', 'transportation', 'instances', 'transport_no_response', 'transport_no_response.xml') self._make_submission(path, self.user.username) self.assertEqual(Instance.objects.count(), count + 1) field = 'transport/available_transportation_types_to_referral_facility' xform = self.user.xforms.all()[0] results = get_form_submissions_grouped_by_field( xform, field, 'available_transportation_types_to_referral_facility') # we should have a similar number of aggregates as submissions as each # submission has a unique value for the field self.assertEqual(len(results), count + 1) # the count where the value is None should have a count of 1 result = filter( lambda r: r['available_transportation_types_to_referral_facility'] is None, results)[0] self.assertEqual(result['count'], 1)
def to_representation(self, obj): if obj is None: return super(SubmissionStatsInstanceSerializer, self)\ .to_representation(obj) request = self.context.get('request') field = request.query_params.get('group') name = request.query_params.get('name', field) if field is None: raise exceptions.ParseError( _(u"Expecting `group` and `name`" u" query parameters.")) try: data = get_form_submissions_grouped_by_field(obj, field, name) except ValueError as e: raise exceptions.ParseError(detail=e) else: if data: element = obj.get_survey_element(field) if element and element.type in SELECT_FIELDS: for record in data: label = obj.get_choice_label(element, record[name]) record[name] = label return data
def build_chart_data_for_field(xform, field): # check if its the special _submission_time META if isinstance(field, basestring) and field == common_tags.SUBMISSION_TIME: field_type = 'datetime' field_name = common_tags.SUBMISSION_TIME else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses field_type = field.type field_name = field.name result = get_form_submissions_grouped_by_field(xform, field_name) data_type = DATA_TYPE_MAP.get(field_type, 'categorized') # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r[field_name] is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_name]): try: r[field_name] = utc_time_string_for_javascript( r[field_name]) except ValueError: pass data = { 'field_name': field_name, 'field_type': field_type, 'data_type': data_type, 'data': result, } return data
def list(self, request, owner=None, formid=None, **kwargs): if owner is None and not request.user.is_anonymous(): owner = request.user.username data = [] if formid: xform = get_xform(formid, request) field = "_submission_time" name = "date_of_submission" group = request.QUERY_PARAMS.get("group", None) alt_name = request.QUERY_PARAMS.get("name", None) if group: name = field = group if alt_name: name = alt_name try: data = get_form_submissions_grouped_by_field(xform, field, name) except ValueError as e: raise exceptions.ParseError(detail=e.message) else: data = self._get_formlist_data_points(request, owner) return Response(data)
def test_get_form_submissions_xform_no_submissions(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() self._publish_xls_file(os.path.join("fixtures", "gps", "gps.xls")) self.xform = self.user.xforms.all().order_by('-pk')[0] fields = ['_submission_time', '_xform_id_string'] count = len(self.xform.instances.all()) self.assertEqual(count, 0) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field) self.assertEqual(result, [])
def test_get_form_submissions_grouped_by_field(self, mock_time): mock_time.return_value = datetime.now() self._make_submissions() count_key = "count" fields = ["_submission_time", "_xform_id_string"] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_xform_no_submissions(self, mock_time): mock_time.return_value = datetime.now() self._make_submissions() self._publish_xls_file(os.path.join("fixtures", "gps", "gps.xls")) self.xform = self.user.xforms.all().order_by("-pk")[0] fields = ["_submission_time", "_xform_id_string"] count = len(self.xform.instances.all()) self.assertEqual(count, 0) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field) self.assertEqual(result, [])
def test_get_form_submissions_grouped_by_field(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() count_key = 'count' fields = ['_submission_time', '_xform_id_string'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() count_key = 'count' fields = ['_submission_time', '_xform_id_string'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field( self.xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field_sets_name(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() count_key = "count" fields = ["_submission_time", "_xform_id_string"] name = "_my_name" xform = self.user.xforms.all()[0] count = len(xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(xform, field, name)[0] self.assertEqual([name, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def build_chart_data_for_field(xform, field, language_index=0): # check if its the special _submission_time META if isinstance(field, basestring) and field == common_tags.SUBMISSION_TIME: field_label = 'Submission Time' field_xpath = '_submission_time' field_type = 'datetime' else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses # check if label is dict i.e. multilang if isinstance(field.label, dict) and len(field.label.keys()) > 0: languages = field.label.keys() language_index = min(language_index, len(languages) - 1) field_label = field.label[languages[language_index]] else: field_label = field.label or field.name field_xpath = field.get_abbreviated_xpath() field_type = field.type result = get_form_submissions_grouped_by_field(xform, field_xpath) result = sorted(result, key=lambda d: d['count']) data_type = DATA_TYPE_MAP.get(field_type, 'categorized') # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r[field_xpath] is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_xpath]): try: r[field_xpath] = utc_time_string_for_javascript( r[field_xpath]) except ValueError: pass data = { 'data': result, 'data_type': data_type, 'field_label': field_label, 'field_xpath': field_xpath, 'field_name': field_xpath.replace('/', '-'), 'field_type': field_type, } return data
def test_get_form_submissions_grouped_by_field_sets_name(self, mock_time): mock_time.return_value = datetime.utcnow().replace(tzinfo=utc) self._make_submissions() count_key = 'count' fields = ['_submission_time', '_xform_id_string'] name = '_my_name' xform = self.user.xforms.all()[0] count = len(xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(xform, field, name)[0] self.assertEqual([name, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field_sets_name(self, mock_time): mock_time.return_value = datetime.now() self._make_submissions() count_key = 'count' fields = ['_submission_time', '_xform_id_string'] name = '_my_name' xform = self.user.xforms.all()[0] count = len(xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field( xform, field, name)[0] self.assertEqual([name, count_key], sorted(result.keys())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field_datetime_to_date(self, mock_time): now = datetime(2014, 01, 01) times = [now, now + timedelta(seconds=1), now + timedelta(seconds=2), now + timedelta(seconds=3)] mock_time.side_effect = times self._make_submissions() count_key = "count" fields = ["_submission_time"] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field(self.xform, field)[0] self.assertEqual([field, count_key], sorted(result.keys())) self.assertEqual(result[field], str(now.date())) self.assertEqual(result[count_key], count)
def test_get_form_submissions_grouped_by_field_datetime_to_date( self, mock_time): now = datetime(2014, 1, 1, tzinfo=utc) times = [now, now + timedelta(seconds=1), now + timedelta(seconds=2), now + timedelta(seconds=3)] mock_time.side_effect = times self._make_submissions() for i in self.xform.instances.all().order_by('-pk'): i.date_created = times.pop() i.save() count_key = 'count' fields = ['_submission_time'] count = len(self.xform.instances.all()) for field in fields: result = get_form_submissions_grouped_by_field( self.xform, field)[0] self.assertEqual([field, count_key], sorted(list(result))) self.assertEqual(result[field], str(now.date())) self.assertEqual(result[count_key], count)
def build_chart_data_for_field(xform, field, language_index=0, choices=None, group_by=None, data_view=None): # check if its the special _submission_time META if isinstance(field, basestring): field_label, field_xpath, field_type = FIELD_DATA_MAP.get(field) else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses field_label = get_field_label(field, language_index) field_xpath = field.get_abbreviated_xpath() field_type = field.type data_type = DATA_TYPE_MAP.get(field_type, 'categorized') field_name = field.name if not isinstance(field, basestring) else field if group_by and isinstance(group_by, list): group_by_name = [ g.get_abbreviated_xpath() if not isinstance(g, basestring) else g for g in group_by ] result = get_form_submissions_aggregated_by_select_one( xform, field_xpath, field_name, group_by_name, data_view) elif group_by: group_by_name = group_by.get_abbreviated_xpath() \ if not isinstance(group_by, basestring) else group_by if (field_type == common_tags.SELECT_ONE or field_name == common_tags.SUBMITTED_BY) and \ isinstance(group_by, six.string_types): result = get_form_submissions_grouped_by_select_one( xform, field_xpath, group_by_name, field_name, data_view) elif field_type in common_tags.NUMERIC_LIST and \ isinstance(group_by, six.string_types): result = get_form_submissions_aggregated_by_select_one( xform, field_xpath, field_name, group_by_name, data_view) elif (field_type == common_tags.SELECT_ONE or field_name == common_tags.SUBMITTED_BY) and \ group_by.type == common_tags.SELECT_ONE: result = get_form_submissions_grouped_by_select_one( xform, field_xpath, group_by_name, field_name, data_view) result = _flatten_multiple_dict_into_one(field_name, group_by_name, result) elif field_type in common_tags.NUMERIC_LIST \ and group_by.type == common_tags.SELECT_ONE: result = get_form_submissions_aggregated_by_select_one( xform, field_xpath, field_name, group_by_name, data_view) else: raise ParseError('Cannot group by %s' % group_by_name) else: result = get_form_submissions_grouped_by_field(xform, field_xpath, field_name, data_view) result = _use_labels_from_field_name( field_name, field, data_type, result, choices=choices) if group_by and not isinstance(group_by, six.string_types + (list, )): group_by_data_type = DATA_TYPE_MAP.get(group_by.type, 'categorized') grp_choices = get_field_choices(group_by, xform) result = _use_labels_from_group_by_name( group_by_name, group_by, group_by_data_type, result, choices=grp_choices) elif group_by and isinstance(group_by, list): for g in group_by: if isinstance(g, six.string_types): continue group_by_data_type = DATA_TYPE_MAP.get(g.type, 'categorized') grp_choices = get_field_choices(g, xform) result = _use_labels_from_group_by_name( g.get_abbreviated_xpath(), g, group_by_data_type, result, choices=grp_choices) if not group_by: result = sorted(result, key=lambda d: d['count']) # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r.get(field_name) is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_name]): try: r[field_name] = utc_time_string_for_javascript( r[field_name]) except ValueError: pass return { 'data': result, 'data_type': data_type, 'field_label': field_label, 'field_xpath': field_xpath, 'field_name': field_name, 'field_type': field_type, 'grouped_by': group_by_name if group_by else None }
def build_chart_data_for_field(xform, field, language_index=0, choices=None, group_by=None, data_view=None): # check if its the special _submission_time META if isinstance(field, basestring): field_label, field_xpath, field_type = FIELD_DATA_MAP.get(field) else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses field_label = get_field_label(field, language_index) field_xpath = field.get_abbreviated_xpath() field_type = field.type data_type = DATA_TYPE_MAP.get(field_type, 'categorized') field_name = field.name if not isinstance(field, basestring) else field if group_by: group_by_name = group_by.get_abbreviated_xpath() \ if not isinstance(group_by, basestring) else group_by if (field_type == common_tags.SELECT_ONE or field_name == common_tags.SUBMITTED_BY) and \ isinstance(group_by, six.string_types): result = get_form_submissions_grouped_by_select_one( xform, field_xpath, group_by_name, field_name, data_view) elif field_type in common_tags.NUMERIC_LIST and \ isinstance(group_by, six.string_types): result = get_form_submissions_aggregated_by_select_one( xform, field_xpath, field_name, group_by_name, data_view) elif (field_type == common_tags.SELECT_ONE or field_name == common_tags.SUBMITTED_BY) and \ group_by.type == common_tags.SELECT_ONE: result = get_form_submissions_grouped_by_select_one( xform, field_xpath, group_by_name, field_name, data_view) result = _flatten_multiple_dict_into_one(field_name, group_by_name, result) elif field_type in common_tags.NUMERIC_LIST \ and group_by.type == common_tags.SELECT_ONE: result = get_form_submissions_aggregated_by_select_one( xform, field_xpath, field_name, group_by_name, data_view) else: raise ParseError(u'Cannot group by %s' % group_by_name) else: result = get_form_submissions_grouped_by_field(xform, field_xpath, field_name, data_view) result = _use_labels_from_field_name(field_name, field, data_type, result, choices=choices) if group_by and not isinstance(group_by, six.string_types): group_by_data_type = DATA_TYPE_MAP.get(group_by.type, 'categorized') grp_choices = get_field_choices(group_by, xform) result = _use_labels_from_group_by_name(group_by_name, group_by, group_by_data_type, result, choices=grp_choices) if not group_by: result = sorted(result, key=lambda d: d['count']) # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r.get(field_name) is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_name]): try: r[field_name] = utc_time_string_for_javascript( r[field_name]) except ValueError: pass return { 'data': result, 'data_type': data_type, 'field_label': field_label, 'field_xpath': field_xpath, 'field_name': field_name, 'field_type': field_type, 'grouped_by': group_by_name if group_by else None }
def build_chart_data_for_field(xform, field, language_index=0, choices=None): # check if its the special _submission_time META if isinstance(field, basestring) and field == common_tags.SUBMISSION_TIME: field_label = 'Submission Time' field_xpath = '_submission_time' field_type = 'datetime' else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses # check if label is dict i.e. multilang if isinstance(field.label, dict) and len(field.label.keys()) > 0: languages = field.label.keys() language_index = min(language_index, len(languages) - 1) field_label = field.label[languages[language_index]] else: field_label = field.label or field.name field_xpath = field.get_abbreviated_xpath() field_type = field.type data_type = DATA_TYPE_MAP.get(field_type, 'categorized') field_name = field.name if not isinstance(field, basestring) else field result = get_form_submissions_grouped_by_field( xform, field_xpath, field_name) # truncate field name to 63 characters to fix #354 truncated_name = field_name[0:POSTGRES_ALIAS_LENGTH] truncated_name = truncated_name.encode('utf-8') if data_type == 'categorized': if result: if field.children: choices = field.children for item in result: item[truncated_name] = get_choice_label( choices, item[truncated_name]) # replace truncated field names in the result set with the field name key field_name = field_name.encode('utf-8') for item in result: if field_name != truncated_name: item[field_name] = item[truncated_name] del(item[truncated_name]) result = sorted(result, key=lambda d: d['count']) # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r.get(field_name) is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_name]): try: r[field_name] = utc_time_string_for_javascript( r[field_name]) except ValueError: pass return { 'data': result, 'data_type': data_type, 'field_label': field_label, 'field_xpath': field_name, 'field_name': field_xpath.replace('/', '-'), 'field_type': field_type }
def get_form_submissions_per_day(xform): """Number of submissions per day for the form.""" return get_form_submissions_grouped_by_field(xform, '_submission_time', 'date')
def build_chart_data_for_field(xform, field, language_index=0, choices=None): # check if its the special _submission_time META if isinstance(field, basestring) and field == common_tags.SUBMISSION_TIME: field_label = 'Submission Time' field_xpath = '_submission_time' field_type = 'datetime' else: # TODO: merge choices with results and set 0's on any missing fields, # i.e. they didn't have responses # check if label is dict i.e. multilang if isinstance(field.label, dict) and len(field.label.keys()) > 0: languages = field.label.keys() language_index = min(language_index, len(languages) - 1) field_label = field.label[languages[language_index]] else: field_label = field.label or field.name field_xpath = field.get_abbreviated_xpath() field_type = field.type data_type = DATA_TYPE_MAP.get(field_type, 'categorized') field_name = field.name if not isinstance(field, basestring) else field result = get_form_submissions_grouped_by_field(xform, field_xpath, field_name) # truncate field name to 63 characters to fix #354 truncated_name = field_name[0:POSTGRES_ALIAS_LENGTH] truncated_name = truncated_name.encode('utf-8') if data_type == 'categorized': if result: if field.children: choices = field.children for item in result: item[truncated_name] = get_choice_label( choices, item[truncated_name]) # replace truncated field names in the result set with the field name key field_name = field_name.encode('utf-8') for item in result: if field_name != truncated_name: item[field_name] = item[truncated_name] del (item[truncated_name]) result = sorted(result, key=lambda d: d['count']) # for date fields, strip out None values if data_type == 'time_based': result = [r for r in result if r.get(field_name) is not None] # for each check if it matches the timezone regexp and convert for js for r in result: if timezone_re.match(r[field_name]): try: r[field_name] = utc_time_string_for_javascript( r[field_name]) except ValueError: pass return { 'data': result, 'data_type': data_type, 'field_label': field_label, 'field_xpath': field_name, 'field_name': field_xpath.replace('/', '-'), 'field_type': field_type }