~ubuntu-branches/debian/sid/python-django/sid

« back to all changes in this revision

Viewing changes to django/db/models/sql/aggregates.py

  • Committer: Package Import Robot
  • Author(s): Raphaël Hertzog
  • Date: 2014-09-17 14:15:11 UTC
  • mfrom: (1.3.17) (6.2.18 experimental)
  • Revision ID: package-import@ubuntu.com-20140917141511-icneokthe9ww5sk4
Tags: 1.7-2
* Release to unstable.
* Add a migrate-south sample script to help users apply their South
  migrations. Thanks to Brian May.

Show diffs side-by-side

added added

removed removed

Lines of Context:
4
4
import copy
5
5
 
6
6
from django.db.models.fields import IntegerField, FloatField
7
 
 
8
 
# Fake fields used to identify aggregate types in data-conversion operations.
9
 
ordinal_aggregate_field = IntegerField()
10
 
computed_aggregate_field = FloatField()
11
 
 
12
 
class Aggregate(object):
 
7
from django.db.models.lookups import RegisterLookupMixin
 
8
from django.utils.functional import cached_property
 
9
 
 
10
 
 
11
__all__ = ['Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance']
 
12
 
 
13
 
 
14
class Aggregate(RegisterLookupMixin):
13
15
    """
14
16
    Default SQL Aggregate.
15
17
    """
55
57
 
56
58
        while tmp and isinstance(tmp, Aggregate):
57
59
            if getattr(tmp, 'is_ordinal', False):
58
 
                tmp = ordinal_aggregate_field
 
60
                tmp = self._ordinal_aggregate_field
59
61
            elif getattr(tmp, 'is_computed', False):
60
 
                tmp = computed_aggregate_field
 
62
                tmp = self._computed_aggregate_field
61
63
            else:
62
64
                tmp = tmp.source
63
65
 
64
66
        self.field = tmp
65
67
 
 
68
    # Two fake fields used to identify aggregate types in data-conversion operations.
 
69
    @cached_property
 
70
    def _ordinal_aggregate_field(self):
 
71
        return IntegerField()
 
72
 
 
73
    @cached_property
 
74
    def _computed_aggregate_field(self):
 
75
        return FloatField()
 
76
 
66
77
    def relabeled_clone(self, change_map):
67
78
        clone = copy.copy(self)
68
79
        if isinstance(self.col, (list, tuple)):
76
87
        if hasattr(self.col, 'as_sql'):
77
88
            field_name, params = self.col.as_sql(qn, connection)
78
89
        elif isinstance(self.col, (list, tuple)):
79
 
            field_name = '.'.join([qn(c) for c in self.col])
 
90
            field_name = '.'.join(qn(c) for c in self.col)
80
91
        else:
81
 
            field_name = self.col
 
92
            field_name = qn(self.col)
82
93
 
83
94
        substitutions = {
84
95
            'function': self.sql_function,
88
99
 
89
100
        return self.sql_template % substitutions, params
90
101
 
 
102
    def get_group_by_cols(self):
 
103
        return []
 
104
 
 
105
    @property
 
106
    def output_field(self):
 
107
        return self.field
 
108
 
91
109
 
92
110
class Avg(Aggregate):
93
111
    is_computed = True
94
112
    sql_function = 'AVG'
95
113
 
 
114
 
96
115
class Count(Aggregate):
97
116
    is_ordinal = True
98
117
    sql_function = 'COUNT'
101
120
    def __init__(self, col, distinct=False, **extra):
102
121
        super(Count, self).__init__(col, distinct='DISTINCT ' if distinct else '', **extra)
103
122
 
 
123
 
104
124
class Max(Aggregate):
105
125
    sql_function = 'MAX'
106
126
 
 
127
 
107
128
class Min(Aggregate):
108
129
    sql_function = 'MIN'
109
130
 
 
131
 
110
132
class StdDev(Aggregate):
111
133
    is_computed = True
112
134
 
114
136
        super(StdDev, self).__init__(col, **extra)
115
137
        self.sql_function = 'STDDEV_SAMP' if sample else 'STDDEV_POP'
116
138
 
 
139
 
117
140
class Sum(Aggregate):
118
141
    sql_function = 'SUM'
119
142
 
 
143
 
120
144
class Variance(Aggregate):
121
145
    is_computed = True
122
146