def group_by(self, queryset, grouping_key=None, bins=None, bin_size=None, **kwargs): """ Return a ValuesQuerySet that has been grouped by this dimension. The group value will be available as grouping_key in the dictionaries. The grouping key defaults to the dimension key. If num_bins or bin_size is not provided, an estimate will be used. .. code-block:: python messages = dim.group_by(messages, 'value', 100) distribution = messages.annotate(count=Count('id')) print distribution[0] # { 'value': 'hello', 'count': 5 } """ # Type checking queryset = find_messages(queryset) expression = self.get_grouping_expression(queryset, bins=bins, bin_size=bin_size, **kwargs) if expression is None: # no results return queryset.values() if expression == self.field_name: # We still have to map back to the requested grouping_key return MappedValuesQuerySet.create_from( queryset.values(expression), {expression: grouping_key}) else: # Sometimes this step gets complicated queryset, internal_key = self.select_grouping_expression( queryset, expression=expression) # Then use values to group by the grouping key. queryset = queryset.values(internal_key) return MappedValuesQuerySet.create_from(queryset, { internal_key: grouping_key, })
def render(self, queryset, desired_primary_bins=None, desired_secondary_bins=None): """ Given a set of messages (already filtered as necessary), calculate the data table. Optionally, a number of primary and secondary bins may be given. The result is a list of dictionaries. Each dictionary contains a key for each dimension and a value key for the count. """ if not self.secondary_dimension: # If there is only one dimension, we should be able to fall back # on that dimension's group_by() implementation. queryset = self.primary_dimension.group_by(queryset, grouping_key=self.primary_dimension.key, bins=desired_primary_bins) return queryset.annotate(value=models.Count('id')) else: # Now it gets nasty... primary_group = self.primary_dimension.get_grouping_expression(queryset, bins=desired_primary_bins) secondary_group = self.secondary_dimension.get_grouping_expression(queryset, bins=desired_secondary_bins) if primary_group is None or secondary_group is None: # There is no data to group return queryset.values() queryset, internal_primary_key = self.primary_dimension.select_grouping_expression( queryset, primary_group) queryset, internal_secondary_key = self.secondary_dimension.select_grouping_expression( queryset, secondary_group) # Group the data queryset = queryset.values(internal_primary_key, internal_secondary_key) # Count the messages queryset = queryset.annotate(value=models.Count('id')) # We may need to remap some fields mapping = {} if internal_primary_key != self.primary_dimension.key: mapping[internal_primary_key] = self.primary_dimension.key if internal_secondary_key != self.secondary_dimension.key: mapping[internal_secondary_key] = self.secondary_dimension.key if len(mapping) > 0: return MappedValuesQuerySet.create_from(queryset, mapping) else: return queryset
def group_by(self, queryset, grouping_key=None, bins=None, bin_size=None, **kwargs): """ Return a ValuesQuerySet that has been grouped by this dimension. The group value will be available as grouping_key in the dictionaries. The grouping key defaults to the dimension key. If num_bins or bin_size is not provided, an estimate will be used. .. code-block:: python messages = dim.group_by(messages, 'value', 100) distribution = messages.annotate(count=Count('id')) print distribution[0] # { 'value': 'hello', 'count': 5 } """ # Type checking queryset = find_messages(queryset) expression = self.get_grouping_expression(queryset, bins=bins, bin_size=bin_size, **kwargs) if expression is None: # no results return queryset.values() if expression == self.field_name: # We still have to map back to the requested grouping_key return MappedValuesQuerySet.create_from(queryset.values(expression), { expression: grouping_key }) else: # Sometimes this step gets complicated queryset, internal_key = self.select_grouping_expression(queryset, expression=expression) # Then use values to group by the grouping key. queryset = queryset.values(internal_key) return MappedValuesQuerySet.create_from(queryset, { internal_key: grouping_key, })
def group_by(self, queryset, grouping_key=None, values_list=False, values_list_flat=False, **kwargs): """ Return a ValuesQuerySet that has been grouped by this dimension. The group value will be available as grouping_key in the dictionaries. The grouping key defaults to the dimension key. .. code-block:: python messages = dim.group_by(messages, 'value') distribution = messages.annotate(count=Count('id')) print distribution[0] # { 'value': 'hello', 'count': 5 } """ if grouping_key is None: grouping_key = self.key # Type checking queryset = find_messages(queryset) # Get the expression that groups this dimension for this queryset grouping_expression = self.get_grouping_expression(queryset, **kwargs) queryset, internal_key = self.select_grouping_expression( queryset, grouping_expression) # Group the data queryset = queryset.values(grouping_expression) if internal_key == grouping_key: return queryset else: # We need to transform the output to match the requested grouping key # queryset = queryset.extra(select={grouping_key: grouping_expression}) return MappedValuesQuerySet.create_from( queryset, {internal_key: grouping_key})
def group_by(self, queryset, grouping_key=None, values_list=False, values_list_flat=False, **kwargs): """ Return a ValuesQuerySet that has been grouped by this dimension. The group value will be available as grouping_key in the dictionaries. The grouping key defaults to the dimension key. .. code-block:: python messages = dim.group_by(messages, 'value') distribution = messages.annotate(count=Count('id')) print distribution[0] # { 'value': 'hello', 'count': 5 } """ if grouping_key is None: grouping_key = self.key # Type checking queryset = find_messages(queryset) # Get the expression that groups this dimension for this queryset grouping_expression = self.get_grouping_expression(queryset, **kwargs) queryset, internal_key = self.select_grouping_expression(queryset, grouping_expression) # Group the data queryset = queryset.values(grouping_expression) if internal_key == grouping_key: return queryset else: # We need to transform the output to match the requested grouping key # queryset = queryset.extra(select={grouping_key: grouping_expression}) return MappedValuesQuerySet.create_from(queryset, { internal_key: grouping_key })
def render(self, queryset, desired_primary_bins=None, desired_secondary_bins=None): """ Given a set of messages (already filtered as necessary), calculate the data table. Optionally, a number of primary and secondary bins may be given. The result is a list of dictionaries. Each dictionary contains a key for each dimension and a value key for the count. """ if not self.secondary_dimension: # If there is only one dimension, we should be able to fall back # on that dimension's group_by() implementation. queryset = self.primary_dimension.group_by( queryset, grouping_key=self.primary_dimension.key, bins=desired_primary_bins) return queryset.annotate(value=models.Count('id')) else: # Now it gets nasty... primary_group = self.primary_dimension.get_grouping_expression( queryset, bins=desired_primary_bins) secondary_group = self.secondary_dimension.get_grouping_expression( queryset, bins=desired_secondary_bins) if primary_group is None or secondary_group is None: # There is no data to group return queryset.values() queryset, internal_primary_key = self.primary_dimension.select_grouping_expression( queryset, primary_group) queryset, internal_secondary_key = self.secondary_dimension.select_grouping_expression( queryset, secondary_group) # Group the data queryset = queryset.values(internal_primary_key, internal_secondary_key) # Count the messages queryset = queryset.annotate(value=models.Count('id')) # We may need to remap some fields mapping = {} if internal_primary_key != self.primary_dimension.key: mapping[internal_primary_key] = self.primary_dimension.key if internal_secondary_key != self.secondary_dimension.key: mapping[internal_secondary_key] = self.secondary_dimension.key if len(mapping) > 0: return MappedValuesQuerySet.create_from(queryset, mapping) else: return queryset