Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "Fixed #16211 -- Added comparison and negation ops to F() expr…

…essions"

This reverts commit 28abf5f.

Conflicts:

	docs/releases/1.5.txt
  • Loading branch information...
commit a8b1861fc4d0a48b4879af803bba094eef145017 1 parent 7f4dbdc
@akaariai akaariai authored
View
3  django/db/backends/__init__.py
@@ -913,9 +913,6 @@ def combine_expression(self, connector, sub_expressions):
can vary between backends (e.g., Oracle with %% and &) and between
subexpression types (e.g., date expressions)
"""
- if connector == 'NOT':
- assert len(sub_expressions) == 1
- return 'NOT (%s)' % sub_expressions[0]
conn = ' %s ' % connector
return conn.join(sub_expressions)
View
37 django/db/models/expressions.py
@@ -18,17 +18,6 @@ class ExpressionNode(tree.Node):
AND = '&'
OR = '|'
- # Unary operator (needs special attention in combine_expression)
- NOT = 'NOT'
-
- # Comparison operators
- EQ = '='
- GE = '>='
- GT = '>'
- LE = '<='
- LT = '<'
- NE = '<>'
-
def __init__(self, children=None, connector=None, negated=False):
if children is not None and len(children) > 1 and connector is None:
raise TypeError('You have to specify a connector.')
@@ -104,32 +93,6 @@ def __rand__(self, other):
def __ror__(self, other):
return self._combine(other, self.OR, True)
- def __invert__(self):
- obj = ExpressionNode([self], connector=self.NOT, negated=True)
- return obj
-
- def __eq__(self, other):
- return self._combine(other, self.EQ, False)
-
- def __ge__(self, other):
- return self._combine(other, self.GE, False)
-
- def __gt__(self, other):
- return self._combine(other, self.GT, False)
-
- def __le__(self, other):
- return self._combine(other, self.LE, False)
-
- def __lt__(self, other):
- return self._combine(other, self.LT, False)
-
- def __ne__(self, other):
- return self._combine(other, self.NE, False)
-
- def __bool__(self):
- raise TypeError('Boolean operators should be avoided. Use bitwise operators.')
- __nonzero__ = __bool__
-
def prepare_database_save(self, unused):
return self
View
8 django/utils/tree.py
@@ -88,12 +88,8 @@ def add(self, node, conn_type):
Otherwise, the whole tree is pushed down one level and a new root
connector is created, connecting the existing tree and the new node.
"""
- # Using for loop with 'is' instead of 'if node in children' so node
- # __eq__ method doesn't get called. The __eq__ method can be overriden
- # by subtypes, for example the F-expression.
- for child in self.children:
- if node is child and conn_type == self.connector:
- return
+ if node in self.children and conn_type == self.connector:
+ return
if len(self.children) < 2:
self.connector = conn_type
if self.connector == conn_type:
View
4 docs/releases/1.5.txt
@@ -177,10 +177,6 @@ Django 1.5 also includes several smaller improvements worth noting:
:setting:`DEBUG` is `True` are sent to the console (unless you redefine the
logger in your :setting:`LOGGING` setting).
-* :ref:`F() expressions <query-expressions>` now support comparison operations
- and inversion, expanding the types of expressions that can be passed to the
- database.
-
* When using :class:`~django.template.RequestContext`, it is now possible to
look up permissions by using ``{% if 'someapp.someperm' in perms %}``
in templates.
View
9 docs/topics/db/queries.txt
@@ -640,15 +640,6 @@ 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
- Comparisons and negation operators for ``F()`` expressions
-
-Django also supports the comparison operators ``==``, ``!=``, ``<=``, ``<``,
-``>``, ``>=`` and the bitwise negation operator ``~`` (boolean ``not`` operator
-will raise ``TypeError``)::
-
- >>> Entry.objects.filter(is_heavily_quoted=~(F('n_pingbacks') < 100))
-
The pk lookup shortcut
----------------------
View
2  tests/modeltests/expressions/models.py
@@ -27,8 +27,6 @@ class Company(models.Model):
Employee,
related_name='company_point_of_contact_set',
null=True)
- is_large = models.BooleanField(
- blank=True)
def __str__(self):
return self.name
View
109 tests/modeltests/expressions/tests.py
@@ -11,22 +11,22 @@
class ExpressionsTests(TestCase):
def test_filter(self):
Company.objects.create(
- name="Example Inc.", num_employees=2300, num_chairs=5, is_large=False,
+ name="Example Inc.", num_employees=2300, num_chairs=5,
ceo=Employee.objects.create(firstname="Joe", lastname="Smith")
)
Company.objects.create(
- name="Foobar Ltd.", num_employees=3, num_chairs=4, is_large=False,
+ name="Foobar Ltd.", num_employees=3, num_chairs=4,
ceo=Employee.objects.create(firstname="Frank", lastname="Meyer")
)
Company.objects.create(
- name="Test GmbH", num_employees=32, num_chairs=1, is_large=False,
+ name="Test GmbH", num_employees=32, num_chairs=1,
ceo=Employee.objects.create(firstname="Max", lastname="Mustermann")
)
company_query = Company.objects.values(
- "name", "num_employees", "num_chairs", "is_large"
+ "name", "num_employees", "num_chairs"
).order_by(
- "name", "num_employees", "num_chairs", "is_large"
+ "name", "num_employees", "num_chairs"
)
# We can filter for companies where the number of employees is greater
@@ -37,13 +37,11 @@ def test_filter(self):
"num_chairs": 5,
"name": "Example Inc.",
"num_employees": 2300,
- "is_large": False
},
{
"num_chairs": 1,
"name": "Test GmbH",
- "num_employees": 32,
- "is_large": False
+ "num_employees": 32
},
],
lambda o: o
@@ -57,20 +55,17 @@ def test_filter(self):
{
"num_chairs": 2300,
"name": "Example Inc.",
- "num_employees": 2300,
- "is_large": False
+ "num_employees": 2300
},
{
"num_chairs": 3,
"name": "Foobar Ltd.",
- "num_employees": 3,
- "is_large": False
+ "num_employees": 3
},
{
"num_chairs": 32,
"name": "Test GmbH",
- "num_employees": 32,
- "is_large": False
+ "num_employees": 32
}
],
lambda o: o
@@ -84,20 +79,17 @@ def test_filter(self):
{
'num_chairs': 2302,
'name': 'Example Inc.',
- 'num_employees': 2300,
- 'is_large': False
+ 'num_employees': 2300
},
{
'num_chairs': 5,
'name': 'Foobar Ltd.',
- 'num_employees': 3,
- 'is_large': False
+ 'num_employees': 3
},
{
'num_chairs': 34,
'name': 'Test GmbH',
- 'num_employees': 32,
- 'is_large': False
+ 'num_employees': 32
}
],
lambda o: o,
@@ -112,20 +104,17 @@ def test_filter(self):
{
'num_chairs': 6900,
'name': 'Example Inc.',
- 'num_employees': 2300,
- 'is_large': False
+ 'num_employees': 2300
},
{
'num_chairs': 9,
'name': 'Foobar Ltd.',
- 'num_employees': 3,
- 'is_large': False
+ 'num_employees': 3
},
{
'num_chairs': 96,
'name': 'Test GmbH',
- 'num_employees': 32,
- 'is_large': False
+ 'num_employees': 32
}
],
lambda o: o,
@@ -140,80 +129,21 @@ def test_filter(self):
{
'num_chairs': 5294600,
'name': 'Example Inc.',
- 'num_employees': 2300,
- 'is_large': False
+ 'num_employees': 2300
},
{
'num_chairs': 15,
'name': 'Foobar Ltd.',
- 'num_employees': 3,
- 'is_large': False
+ 'num_employees': 3
},
{
'num_chairs': 1088,
'name': 'Test GmbH',
- 'num_employees': 32,
- 'is_large': False
+ 'num_employees': 32
}
],
lambda o: o,
)
- # The comparison operators and the bitwise unary not can be used
- # to assign to boolean fields
- for expression in (
- # Check boundaries
- ~(F('num_employees') < 33),
- ~(F('num_employees') <= 32),
- (F('num_employees') > 2299),
- (F('num_employees') >= 2300),
- (F('num_employees') == 2300),
- ((F('num_employees') + 1 != 4) & (32 != F('num_employees'))),
- # Inverted argument order works too
- (2299 < F('num_employees')),
- (2300 <= F('num_employees'))
- ):
- # Test update by F-expression
- company_query.update(
- is_large=expression
- )
- # Compare results
- self.assertQuerysetEqual(
- company_query, [
- {
- 'num_chairs': 5294600,
- 'name': 'Example Inc.',
- 'num_employees': 2300,
- 'is_large': True
- },
- {
- 'num_chairs': 15,
- 'name': 'Foobar Ltd.',
- 'num_employees': 3,
- 'is_large': False
- },
- {
- 'num_chairs': 1088,
- 'name': 'Test GmbH',
- 'num_employees': 32,
- 'is_large': False
- }
- ],
- lambda o: o,
- )
- # Reset values
- company_query.update(
- is_large=False
- )
-
- # The python boolean operators should be avoided as they yield
- # unexpected results
- test_gmbh = Company.objects.get(name="Test GmbH")
- with self.assertRaises(TypeError):
- test_gmbh.is_large = not F('is_large')
- with self.assertRaises(TypeError):
- test_gmbh.is_large = F('is_large') and F('is_large')
- with self.assertRaises(TypeError):
- test_gmbh.is_large = F('is_large') or F('is_large')
# The relation of a foreign key can become copied over to an other
# foreign key.
@@ -272,8 +202,9 @@ def test_filter(self):
test_gmbh.point_of_contact = None
test_gmbh.save()
self.assertTrue(test_gmbh.point_of_contact is None)
- with self.assertRaises(ValueError):
+ def test():
test_gmbh.point_of_contact = F("ceo")
+ self.assertRaises(ValueError, test)
test_gmbh.point_of_contact = test_gmbh.ceo
test_gmbh.save()
Please sign in to comment.
Something went wrong with that request. Please try again.