Parcourir la source

Update managers.py

Fixes for Django 1.6 (as of beta 1)
Jay McEntire il y a 11 ans
Parent
commit
190bc02499
1 fichiers modifiés avec 51 ajouts et 11 suppressions
  1. 51 11
      netfields/managers.py

+ 51 - 11
netfields/managers.py

@@ -1,7 +1,9 @@
 from netaddr import IPNetwork
 
+from django import VERSION
 from django.db import models, connection
 from django.db.backends.postgresql_psycopg2.base import DatabaseWrapper
+from django.db.models.fields import DateTimeField
 from django.db.models import sql, query
 from django.db.models.query_utils import QueryWrapper
 from django.utils import tree
@@ -30,27 +32,32 @@ class NetQuery(sql.Query):
 
 
 class NetWhere(sql.where.WhereNode):
-    def add(self, data, connector):
+
+
+    def _prepare_data(self, data):
         """
-        Special form of WhereNode.add() that does not automatically consume the
-        __iter__ method of IPNetwork objects.
+        Prepare data for addition to the tree. If the data is a list or tuple,
+        it is expected to be of the form (obj, lookup_type, value), where obj
+        is a Constraint object, and is then slightly munged before being
+        stored (to avoid storing any reference to field objects). Otherwise,
+        the 'data' is stored unchanged and can be any class with an 'as_sql()'
+        method.
         """
         if not isinstance(data, (list, tuple)):
-            # Need to bypass WhereNode
-            tree.Node.add(self, data, connector)
-            return
-
+            return data
         obj, lookup_type, value = data
         if not isinstance(value, IPNetwork) and hasattr(value, '__iter__') and hasattr(value, 'next'):
             # Consume any generators immediately, so that we can determine
             # emptiness and transform any non-empty values correctly.
             value = list(value)
 
+
         # The "value_annotation" parameter is used to pass auxilliary information
         # about the value(s) to the query construction. Specifically, datetime
         # and empty values need special handling. Other types could be used
         # here in the future (using Python types is suggested for consistency).
-        if isinstance(value, datetime.datetime):
+        if (isinstance(value, datetime.datetime)
+            or (isinstance(obj.field, DateTimeField) and lookup_type != 'isnull')):
             value_annotation = datetime.datetime
         elif hasattr(value, 'value_annotation'):
             value_annotation = value.value_annotation
@@ -59,10 +66,43 @@ class NetWhere(sql.where.WhereNode):
 
         if hasattr(obj, "prepare"):
             value = obj.prepare(lookup_type, value)
+        return (obj, lookup_type, value_annotation, value)
+
+
+    if VERSION[:2] < (1, 6):
+        def add(self, data, connector):
+            """
+            Special form of WhereNode.add() that does not automatically consume the
+            __iter__ method of IPNetwork objects.
+            """
+            if not isinstance(data, (list, tuple)):
+                # Need to bypass WhereNode
+                tree.Node.add(self, data, connector)
+                return
+
+            obj, lookup_type, value = data
+            if not isinstance(value, IPNetwork) and hasattr(value, '__iter__') and hasattr(value, 'next'):
+                # Consume any generators immediately, so that we can determine
+                # emptiness and transform any non-empty values correctly.
+                value = list(value)
+
+            # The "value_annotation" parameter is used to pass auxilliary information
+            # about the value(s) to the query construction. Specifically, datetime
+            # and empty values need special handling. Other types could be used
+            # here in the future (using Python types is suggested for consistency).
+            if isinstance(value, datetime.datetime):
+                value_annotation = datetime.datetime
+            elif hasattr(value, 'value_annotation'):
+                value_annotation = value.value_annotation
+            else:
+                value_annotation = bool(value)
 
-        # Need to bypass WhereNode
-        tree.Node.add(self,
-            (obj, lookup_type, value_annotation, value), connector)
+            if hasattr(obj, "prepare"):
+                value = obj.prepare(lookup_type, value)
+
+            # Need to bypass WhereNode
+            tree.Node.add(self,
+                (obj, lookup_type, value_annotation, value), connector)
 
     def make_atom(self, child, qn, conn):
         lvalue, lookup_type, value_annot, params_or_value = child