Made it possible to pickle DateQuerySets.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8455 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Malcolm Tredinnick 2008-08-20 22:38:15 +00:00
parent eb85af1865
commit b9407b26df
4 changed files with 31 additions and 11 deletions

View File

@ -452,12 +452,8 @@ class QuerySet(object):
"'kind' must be one of 'year', 'month' or 'day'." "'kind' must be one of 'year', 'month' or 'day'."
assert order in ('ASC', 'DESC'), \ assert order in ('ASC', 'DESC'), \
"'order' must be either 'ASC' or 'DESC'." "'order' must be either 'ASC' or 'DESC'."
# Let the FieldDoesNotExist exception propagate. return self._clone(klass=DateQuerySet, setup=True,
field = self.model._meta.get_field(field_name, many_to_many=False) _field_name=field_name, _kind=kind, _order=order)
assert isinstance(field, DateField), "%r isn't a DateField." \
% field_name
return self._clone(klass=DateQuerySet, setup=True, _field=field,
_kind=kind, _order=order)
def none(self): def none(self):
""" """
@ -721,13 +717,16 @@ class DateQuerySet(QuerySet):
""" """
self.query = self.query.clone(klass=sql.DateQuery, setup=True) self.query = self.query.clone(klass=sql.DateQuery, setup=True)
self.query.select = [] self.query.select = []
self.query.add_date_select(self._field, self._kind, self._order) field = self.model._meta.get_field(self._field_name, many_to_many=False)
if self._field.null: assert isinstance(field, DateField), "%r isn't a DateField." \
self.query.add_filter(('%s__isnull' % self._field.name, False)) % 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): def _clone(self, klass=None, setup=False, **kwargs):
c = super(DateQuerySet, self)._clone(klass, False, **kwargs) c = super(DateQuerySet, self)._clone(klass, False, **kwargs)
c._field = self._field c._field_name = self._field_name
c._kind = self._kind c._kind = self._kind
if setup and hasattr(c, '_setup_query'): if setup and hasattr(c, '_setup_query'):
c._setup_query() c._setup_query()

View File

@ -85,7 +85,7 @@ class Date(object):
def __init__(self, col, lookup_type, date_sql_func): def __init__(self, col, lookup_type, date_sql_func):
self.col = col self.col = col
self.lookup_type = lookup_type 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): def relabel_aliases(self, change_map):
c = self.col c = self.col

View File

@ -343,6 +343,23 @@ class DateQuery(Query):
date field. This requires some special handling when converting the results date field. This requires some special handling when converting the results
back to Python objects, so we put it in a separate class. 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): def results_iter(self):
""" """
Returns an iterator over the results from executing this query. Returns an iterator over the results from executing this query.

View File

@ -897,6 +897,10 @@ Bug #8283 -- Checking that applying filters after a disjunction works correctly.
>>> (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=n1)).filter(note=n1) >>> (ExtraInfo.objects.filter(info='e2')|ExtraInfo.objects.filter(note=n1)).filter(note=n1)
[<ExtraInfo: e1>] [<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 # In Python 2.3, exceptions raised in __len__ are swallowed (Python issue