Permalink
Browse files

Added chaining of calculations, so that you can reuse variables from …

…earlier calculations.
  • Loading branch information...
joshbohde committed Jan 7, 2011
1 parent a408085 commit 7453c885af13ccd2787c9535c34eff69bf004cd3
Showing with 27 additions and 3 deletions.
  1. +4 −0 README.md
  2. +3 −3 db_calculations/query.py
  3. +20 −0 tests/basic/tests.py
View
@@ -39,6 +39,10 @@ Now you can use the calculate method, using the builtin F objects to build your
>>> Number.objects.calculate(z=F('x')/F('y'))[0].z
... 0.66666666666666663
+ >>> Number.objects.calculate(z=F('x')+F('y')).calculate(z_squared=F('z')*F('z'))[0].z_squared
+ ... 25.0
+
+
## Warning
The current state is more of a proof of concept than any sort of thing you might want to use for your project. It pretty much won't work outside of basic operations. In fact, it will go pretty crazy once you start to do anything fancy.
View
@@ -9,7 +9,7 @@ class CalculationEvaluator(SQLEvaluator):
def as_sql(self, qn, connection, **extra):
statement, values = super(CalculationEvaluator, self).as_sql(qn, connection)
- return statement % tuple(values)
+ return '(%s)' % (statement % tuple(values))
class Calculation(object):
@@ -20,8 +20,8 @@ def __init__(self, **kwargs):
def add_to_query(self, query, used_aliases):
# Add the model fields to the query so that calculating the
# aggregate field is correct
-
- query.add_fields([f.name for f in query.get_meta().fields])
+ if not query.select:
+ query.add_fields([f.name for f in query.get_meta().fields])
for alias, calculation in self.calcs.iteritems():
c = CalculationEvaluator(calculation, query)
View
@@ -35,3 +35,23 @@ def test_basic_div(self):
self.assertEqual(number.y, 3)
+class Chaining(TestCase):
+ def setUp(self):
+ Number.objects.create(x=2,y=3)
+
+ def test_square_addition(self):
+ number = Number.objects.calculate(z=F('x')+F('y'))
+ number = number.calculate(z_squared=F('z')*F('z'))[0]
+ self.assertEqual(number.z_squared, 25)
+ self.assertEqual(number.z, 5)
+ self.assertEqual(number.x, 2)
+ self.assertEqual(number.y, 3)
+
+ def test_square_mult(self):
+ number = Number.objects.calculate(z=F('x')*F('y'))
+ number = number.calculate(z_squared=F('z')*F('z'))[0]
+ self.assertEqual(number.z_squared, 36)
+ self.assertEqual(number.z, 6)
+ self.assertEqual(number.x, 2)
+ self.assertEqual(number.y, 3)
+

0 comments on commit 7453c88

Please sign in to comment.