diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 78dbbc6..a9cfc4b 100644
a
|
b
|
class BaseDatabaseOperations(object):
|
526 | 526 | """ |
527 | 527 | return "%s" |
528 | 528 | |
| 529 | def decimal_cast_sql(self, max_digits, decimal_places): |
| 530 | """ |
| 531 | FIXME: documentation |
| 532 | """ |
| 533 | return "%s" |
| 534 | |
529 | 535 | def deferrable_sql(self): |
530 | 536 | """ |
531 | 537 | Returns the SQL necessary to make a constraint "initially deferred" |
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index f24df93..940200b 100644
a
|
b
|
class DatabaseOperations(BaseDatabaseOperations):
|
222 | 222 | return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector, |
223 | 223 | timedelta.days, timedelta.seconds, timedelta.microseconds) |
224 | 224 | |
| 225 | def decimal_cast_sql(self, max_digits, decimal_places): |
| 226 | """ |
| 227 | FIXME: documentation |
| 228 | """ |
| 229 | return "CAST(%%s AS DECIMAL(%d, %d))" % (max_digits, decimal_places) |
| 230 | |
225 | 231 | def drop_foreignkey_sql(self): |
226 | 232 | return "DROP FOREIGN KEY" |
227 | 233 | |
diff --git a/django/db/models/sql/where.py b/django/db/models/sql/where.py
index 3e4b352..eff1a12 100644
a
|
b
|
from __future__ import absolute_import
|
6 | 6 | |
7 | 7 | import collections |
8 | 8 | import datetime |
| 9 | import decimal |
| 10 | import re |
9 | 11 | from itertools import repeat |
10 | 12 | |
11 | 13 | from django.utils import tree |
… |
… |
from django.utils.six.moves import xrange
|
18 | 20 | AND = 'AND' |
19 | 21 | OR = 'OR' |
20 | 22 | |
| 23 | # Extract precision from decimal field info |
| 24 | DECIMAL_PRECISION_RE = re.compile(r'^\D+(\d+)\D+(\d+)\D+$') |
| 25 | |
21 | 26 | class EmptyShortCircuit(Exception): |
22 | 27 | """ |
23 | 28 | Internal exception used to indicate that a "matches nothing" node should be |
… |
… |
class WhereNode(tree.Node):
|
62 | 67 | # here in the future (using Python types is suggested for consistency). |
63 | 68 | if isinstance(value, datetime.datetime): |
64 | 69 | value_annotation = datetime.datetime |
| 70 | elif isinstance(value, decimal.Decimal): |
| 71 | value_annotation = decimal.Decimal |
65 | 72 | elif hasattr(value, 'value_annotation'): |
66 | 73 | value_annotation = value.value_annotation |
67 | 74 | else: |
… |
… |
class WhereNode(tree.Node):
|
176 | 183 | |
177 | 184 | if value_annotation is datetime.datetime: |
178 | 185 | cast_sql = connection.ops.datetime_cast_sql() |
| 186 | elif value_annotation is decimal.Decimal: |
| 187 | # lvalue[2] holds something like 'numeric(12, 6)' |
| 188 | precision_match = DECIMAL_PRECISION_RE.match(lvalue[2]) |
| 189 | max_digits, dec_places = [int(i) for i in precision_match.groups()] |
| 190 | cast_sql = connection.ops.decimal_cast_sql(max_digits, dec_places) |
| 191 | del precision_match |
| 192 | del max_digits |
| 193 | del dec_places |
179 | 194 | else: |
180 | 195 | cast_sql = '%s' |
181 | 196 | |