Loading django/db/backends/__init__.py +3 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,9 @@ class BaseDatabaseOperations(object): 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) Loading django/db/models/expressions.py +37 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,17 @@ 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.') Loading Loading @@ -93,6 +104,32 @@ class ExpressionNode(tree.Node): 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 Loading django/utils/tree.py +6 −2 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ class Node(object): Otherwise, the whole tree is pushed down one level and a new root connector is created, connecting the existing tree and the new node. """ if node in self.children and conn_type == self.connector: # 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 len(self.children) < 2: self.connector = conn_type Loading docs/releases/1.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,10 @@ 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. Backwards incompatible changes in 1.5 ===================================== Loading docs/topics/db/queries.txt +9 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,15 @@ 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 ---------------------- Loading Loading
django/db/backends/__init__.py +3 −0 Original line number Diff line number Diff line Loading @@ -913,6 +913,9 @@ class BaseDatabaseOperations(object): 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) Loading
django/db/models/expressions.py +37 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,17 @@ 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.') Loading Loading @@ -93,6 +104,32 @@ class ExpressionNode(tree.Node): 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 Loading
django/utils/tree.py +6 −2 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ class Node(object): Otherwise, the whole tree is pushed down one level and a new root connector is created, connecting the existing tree and the new node. """ if node in self.children and conn_type == self.connector: # 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 len(self.children) < 2: self.connector = conn_type Loading
docs/releases/1.5.txt +4 −0 Original line number Diff line number Diff line Loading @@ -176,6 +176,10 @@ 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. Backwards incompatible changes in 1.5 ===================================== Loading
docs/topics/db/queries.txt +9 −0 Original line number Diff line number Diff line Loading @@ -640,6 +640,15 @@ 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 ---------------------- Loading