Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Made it possible to pickle DateQuerySets.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8455 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit b9407b26dff47232d57133d93593a1a50eee1cc5 1 parent eb85af1
Malcolm Tredinnick authored August 20, 2008
19  django/db/models/query.py
@@ -452,12 +452,8 @@ def dates(self, field_name, kind, order='ASC'):
452 452
                 "'kind' must be one of 'year', 'month' or 'day'."
453 453
         assert order in ('ASC', 'DESC'), \
454 454
                 "'order' must be either 'ASC' or 'DESC'."
455  
-        # Let the FieldDoesNotExist exception propagate.
456  
-        field = self.model._meta.get_field(field_name, many_to_many=False)
457  
-        assert isinstance(field, DateField), "%r isn't a DateField." \
458  
-                % field_name
459  
-        return self._clone(klass=DateQuerySet, setup=True, _field=field,
460  
-                _kind=kind, _order=order)
  455
+        return self._clone(klass=DateQuerySet, setup=True,
  456
+                _field_name=field_name, _kind=kind, _order=order)
461 457
 
462 458
     def none(self):
463 459
         """
@@ -721,13 +717,16 @@ def _setup_query(self):
721 717
         """
722 718
         self.query = self.query.clone(klass=sql.DateQuery, setup=True)
723 719
         self.query.select = []
724  
-        self.query.add_date_select(self._field, self._kind, self._order)
725  
-        if self._field.null:
726  
-            self.query.add_filter(('%s__isnull' % self._field.name, False))
  720
+        field = self.model._meta.get_field(self._field_name, many_to_many=False)
  721
+        assert isinstance(field, DateField), "%r isn't a DateField." \
  722
+                % field_name
  723
+        self.query.add_date_select(field, self._kind, self._order)
  724
+        if field.null:
  725
+            self.query.add_filter(('%s__isnull' % field.name, False))
727 726
 
728 727
     def _clone(self, klass=None, setup=False, **kwargs):
729 728
         c = super(DateQuerySet, self)._clone(klass, False, **kwargs)
730  
-        c._field = self._field
  729
+        c._field_name = self._field_name
731 730
         c._kind = self._kind
732 731
         if setup and hasattr(c, '_setup_query'):
733 732
             c._setup_query()
2  django/db/models/sql/datastructures.py
@@ -85,7 +85,7 @@ class Date(object):
85 85
     def __init__(self, col, lookup_type, date_sql_func):
86 86
         self.col = col
87 87
         self.lookup_type = lookup_type
88  
-        self.date_sql_func= date_sql_func
  88
+        self.date_sql_func = date_sql_func
89 89
 
90 90
     def relabel_aliases(self, change_map):
91 91
         c = self.col
17  django/db/models/sql/subqueries.py
@@ -343,6 +343,23 @@ class DateQuery(Query):
343 343
     date field. This requires some special handling when converting the results
344 344
     back to Python objects, so we put it in a separate class.
345 345
     """
  346
+    def __getstate__(self):
  347
+        """
  348
+        Special DateQuery-specific pickle handling.
  349
+        """
  350
+        for elt in self.select:
  351
+            if isinstance(elt, Date):
  352
+                # Eliminate a method reference that can't be pickled. The
  353
+                # __setstate__ method restores this.
  354
+                elt.date_sql_func = None
  355
+        return super(DateQuery, self).__getstate__()
  356
+
  357
+    def __setstate__(self, obj_dict):
  358
+        super(DateQuery, self).__setstate__(obj_dict)
  359
+        for elt in self.select:
  360
+            if isinstance(elt, Date):
  361
+                self.date_sql_func = self.connection.ops.date_trunc_sql
  362
+
346 363
     def results_iter(self):
347 364
         """
348 365
         Returns an iterator over the results from executing this query.
4  tests/regressiontests/queries/models.py
@@ -897,6 +897,10 @@ class Join(models.Model):
897 897
 >>> (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=n1)).filter(note=n1)
898 898
 [<ExtraInfo: e1>]
899 899
 
  900
+Pickling of DateQuerySets used to fail
  901
+>>> qs = Item.objects.dates('created', 'month')
  902
+>>> _ = pickle.loads(pickle.dumps(qs))
  903
+
900 904
 """}
901 905
 
902 906
 # In Python 2.3, exceptions raised in __len__ are swallowed (Python issue

0 notes on commit b9407b2

Please sign in to comment.
Something went wrong with that request. Please try again.