Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Moved F() '&' and '|' to .bitand() and .bitor()

Done for consistency with Q() expressions and QuerySet combining. This
will allow usage of '&' and '|' as boolean logical operators in the
future. Refs #16211.
  • Loading branch information...
commit b625e8272bd41714c838cfda3fb54e1f5177f009 1 parent a8b1861
@akaariai akaariai authored
View
30 django/db/models/expressions.py
@@ -14,9 +14,11 @@ class ExpressionNode(tree.Node):
# because it can be used in strings that also
# have parameter substitution.
- # Bitwise operators
- AND = '&'
- OR = '|'
+ # Bitwise operators - note that these are generated by .bitand()
+ # and .bitor(), the '&' and '|' are reserved for boolean operator
+ # usage.
+ BITAND = '&'
+ BITOR = '|'
def __init__(self, children=None, connector=None, negated=False):
if children is not None and len(children) > 1 and connector is None:
@@ -66,10 +68,20 @@ def __mod__(self, other):
return self._combine(other, self.MOD, False)
def __and__(self, other):
- return self._combine(other, self.AND, False)
+ raise NotImplementedError(
+ "Use .bitand() and .bitor() for bitwise logical operations."
+ )
+
+ def bitand(self, other):
+ return self._combine(other, self.BITAND, False)
def __or__(self, other):
- return self._combine(other, self.OR, False)
+ raise NotImplementedError(
+ "Use .bitand() and .bitor() for bitwise logical operations."
+ )
+
+ def bitor(self, other):
+ return self._combine(other, self.BITOR, False)
def __radd__(self, other):
return self._combine(other, self.ADD, True)
@@ -88,10 +100,14 @@ def __rmod__(self, other):
return self._combine(other, self.MOD, True)
def __rand__(self, other):
- return self._combine(other, self.AND, True)
+ raise NotImplementedError(
+ "Use .bitand() and .bitor() for bitwise logical operations."
+ )
def __ror__(self, other):
- return self._combine(other, self.OR, True)
+ raise NotImplementedError(
+ "Use .bitand() and .bitor() for bitwise logical operations."
+ )
def prepare_database_save(self, unused):
return self
View
6 docs/releases/1.5.txt
@@ -438,6 +438,12 @@ Miscellaneous
needs. The new default value is `0666` (octal) and the current umask value
is first masked out.
+* The :ref:`F() expressions <query-expressions>` supported bitwise operators by
+ ``&`` and ``|``. These operators are now available using ``.bitand()`` and
+ ``.bitor()`` instead. The removal of ``&`` and ``|`` was done to be consistent with
+ :ref:`Q() expressions <complex-lookups-with-q>` and ``QuerySet`` combining where
+ the operators are used as boolean AND and OR operators.
+
Features deprecated in 1.5
==========================
View
12 docs/topics/db/queries.txt
@@ -640,6 +640,18 @@ that were modified more than 3 days after they were published::
>>> from datetime import timedelta
>>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))
+.. versionadded:: 1.5
+ ``.bitand()`` and ``.bitor()``
+
+The ``F()`` objects now support bitwise operations by ``.bitand()`` and
+``.bitor()``, for example::
+
+ >>> F('somefield').bitand(16)
+
+.. versionchanged:: 1.5
+ The previously undocumented operators ``&`` and ``|`` no longer produce
+ bitwise operations, use ``.bitand()`` and ``.bitor()`` instead.
+
The pk lookup shortcut
----------------------
View
18 tests/regressiontests/expressions_regress/tests.py
@@ -128,7 +128,7 @@ def test_lefthand_modulo(self):
def test_lefthand_bitwise_and(self):
# LH Bitwise ands on integers
- Number.objects.filter(pk=self.n.pk).update(integer=F('integer') & 56)
+ Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitand(56))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 40)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
@@ -136,7 +136,7 @@ def test_lefthand_bitwise_and(self):
@skipUnlessDBFeature('supports_bitwise_or')
def test_lefthand_bitwise_or(self):
# LH Bitwise or on integers
- Number.objects.filter(pk=self.n.pk).update(integer=F('integer') | 48)
+ Number.objects.filter(pk=self.n.pk).update(integer=F('integer').bitor(48))
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 58)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
@@ -181,20 +181,6 @@ def test_right_hand_modulo(self):
self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 27)
self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
- def test_right_hand_bitwise_and(self):
- # RH Bitwise ands on integers
- Number.objects.filter(pk=self.n.pk).update(integer=15 & F('integer'))
-
- self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 10)
- self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
-
- @skipUnlessDBFeature('supports_bitwise_or')
- def test_right_hand_bitwise_or(self):
- # RH Bitwise or on integers
- Number.objects.filter(pk=self.n.pk).update(integer=15 | F('integer'))
-
- self.assertEqual(Number.objects.get(pk=self.n.pk).integer, 47)
- self.assertEqual(Number.objects.get(pk=self.n.pk).float, Approximate(15.500, places=3))
class FTimeDeltaTests(TestCase):
Please sign in to comment.
Something went wrong with that request. Please try again.