Esempio n. 1
0
    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,
            })
Esempio n. 2
0
    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
Esempio n. 3
0
    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,
            })
Esempio n. 4
0
    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})
Esempio n. 5
0
    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
            })
Esempio n. 6
0
    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