Author: mtredinnick
Date: 2008-08-20 17:38:15 -0500 (Wed, 20 Aug 2008)
New Revision: 8455

Modified:
   django/trunk/django/db/models/query.py
   django/trunk/django/db/models/sql/datastructures.py
   django/trunk/django/db/models/sql/subqueries.py
   django/trunk/tests/regressiontests/queries/models.py
Log:
Made it possible to pickle DateQuerySets.


Modified: django/trunk/django/db/models/query.py
===================================================================
--- django/trunk/django/db/models/query.py      2008-08-20 22:30:43 UTC (rev 
8454)
+++ django/trunk/django/db/models/query.py      2008-08-20 22:38:15 UTC (rev 
8455)
@@ -452,12 +452,8 @@
                 "'kind' must be one of 'year', 'month' or 'day'."
         assert order in ('ASC', 'DESC'), \
                 "'order' must be either 'ASC' or 'DESC'."
-        # Let the FieldDoesNotExist exception propagate.
-        field = self.model._meta.get_field(field_name, many_to_many=False)
-        assert isinstance(field, DateField), "%r isn't a DateField." \
-                % field_name
-        return self._clone(klass=DateQuerySet, setup=True, _field=field,
-                _kind=kind, _order=order)
+        return self._clone(klass=DateQuerySet, setup=True,
+                _field_name=field_name, _kind=kind, _order=order)
 
     def none(self):
         """
@@ -721,13 +717,16 @@
         """
         self.query = self.query.clone(klass=sql.DateQuery, setup=True)
         self.query.select = []
-        self.query.add_date_select(self._field, self._kind, self._order)
-        if self._field.null:
-            self.query.add_filter(('%s__isnull' % self._field.name, False))
+        field = self.model._meta.get_field(self._field_name, 
many_to_many=False)
+        assert isinstance(field, DateField), "%r isn't a DateField." \
+                % field_name
+        self.query.add_date_select(field, self._kind, self._order)
+        if field.null:
+            self.query.add_filter(('%s__isnull' % field.name, False))
 
     def _clone(self, klass=None, setup=False, **kwargs):
         c = super(DateQuerySet, self)._clone(klass, False, **kwargs)
-        c._field = self._field
+        c._field_name = self._field_name
         c._kind = self._kind
         if setup and hasattr(c, '_setup_query'):
             c._setup_query()

Modified: django/trunk/django/db/models/sql/datastructures.py
===================================================================
--- django/trunk/django/db/models/sql/datastructures.py 2008-08-20 22:30:43 UTC 
(rev 8454)
+++ django/trunk/django/db/models/sql/datastructures.py 2008-08-20 22:38:15 UTC 
(rev 8455)
@@ -85,7 +85,7 @@
     def __init__(self, col, lookup_type, date_sql_func):
         self.col = col
         self.lookup_type = lookup_type
-        self.date_sql_func= date_sql_func
+        self.date_sql_func = date_sql_func
 
     def relabel_aliases(self, change_map):
         c = self.col

Modified: django/trunk/django/db/models/sql/subqueries.py
===================================================================
--- django/trunk/django/db/models/sql/subqueries.py     2008-08-20 22:30:43 UTC 
(rev 8454)
+++ django/trunk/django/db/models/sql/subqueries.py     2008-08-20 22:38:15 UTC 
(rev 8455)
@@ -343,6 +343,23 @@
     date field. This requires some special handling when converting the results
     back to Python objects, so we put it in a separate class.
     """
+    def __getstate__(self):
+        """
+        Special DateQuery-specific pickle handling.
+        """
+        for elt in self.select:
+            if isinstance(elt, Date):
+                # Eliminate a method reference that can't be pickled. The
+                # __setstate__ method restores this.
+                elt.date_sql_func = None
+        return super(DateQuery, self).__getstate__()
+
+    def __setstate__(self, obj_dict):
+        super(DateQuery, self).__setstate__(obj_dict)
+        for elt in self.select:
+            if isinstance(elt, Date):
+                self.date_sql_func = self.connection.ops.date_trunc_sql
+
     def results_iter(self):
         """
         Returns an iterator over the results from executing this query.

Modified: django/trunk/tests/regressiontests/queries/models.py
===================================================================
--- django/trunk/tests/regressiontests/queries/models.py        2008-08-20 
22:30:43 UTC (rev 8454)
+++ django/trunk/tests/regressiontests/queries/models.py        2008-08-20 
22:38:15 UTC (rev 8455)
@@ -897,6 +897,10 @@
 >>> (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=n1)).filter(note=n1)
 [<ExtraInfo: e1>]
 
+Pickling of DateQuerySets used to fail
+>>> qs = Item.objects.dates('created', 'month')
+>>> _ = pickle.loads(pickle.dumps(qs))
+
 """}
 
 # In Python 2.3, exceptions raised in __len__ are swallowed (Python issue


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to