diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 2c2bcd541a..1d3a15048e 100644 --- a/django/contrib/admin/options.py +++ b/django/contrib/admin/options.py @@ -73,7 +73,9 @@ class BaseModelAdmin(object): readonly_fields = () def __init__(self): - self.formfield_overrides = dict(FORMFIELD_FOR_DBFIELD_DEFAULTS, **self.formfield_overrides) + overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy() + overrides.update(self.formfield_overrides) + self.formfield_overrides = overrides def formfield_for_dbfield(self, db_field, **kwargs): """ diff --git a/django/core/cache/backends/filebased.py b/django/core/cache/backends/filebased.py index 91f0b78fa6..fe833336d0 100644 --- a/django/core/cache/backends/filebased.py +++ b/django/core/cache/backends/filebased.py @@ -42,13 +42,15 @@ class CacheClass(BaseCache): fname = self._key_to_file(key) try: f = open(fname, 'rb') - exp = pickle.load(f) - now = time.time() - if exp < now: + try: + exp = pickle.load(f) + now = time.time() + if exp < now: + self._delete(fname) + else: + return pickle.load(f) + finally: f.close() - self._delete(fname) - else: - return pickle.load(f) except (IOError, OSError, EOFError, pickle.PickleError): pass return default @@ -67,9 +69,12 @@ class CacheClass(BaseCache): os.makedirs(dirname) f = open(fname, 'wb') - now = time.time() - pickle.dump(now + timeout, f, pickle.HIGHEST_PROTOCOL) - pickle.dump(value, f, pickle.HIGHEST_PROTOCOL) + try: + now = time.time() + pickle.dump(now + timeout, f, pickle.HIGHEST_PROTOCOL) + pickle.dump(value, f, pickle.HIGHEST_PROTOCOL) + finally: + f.close() except (IOError, OSError): pass @@ -93,14 +98,16 @@ class CacheClass(BaseCache): fname = self._key_to_file(key) try: f = open(fname, 'rb') - exp = pickle.load(f) - now = time.time() - if exp < now: + try: + exp = pickle.load(f) + now = time.time() + if exp < now: + self._delete(fname) + return False + else: + return True + finally: f.close() - self._delete(fname) - return False - else: - return True except (IOError, OSError, EOFError, pickle.PickleError): return False diff --git a/tests/modeltests/aggregation/models.py b/tests/modeltests/aggregation/models.py index e5f0f5d318..74e43b8cc6 100644 --- a/tests/modeltests/aggregation/models.py +++ b/tests/modeltests/aggregation/models.py @@ -191,8 +191,8 @@ u'The Definitive Guide to Django: Web Development Done Right' # Calling values on a queryset that has annotations returns the output # as a dictionary ->>> Book.objects.filter(pk=1).annotate(mean_age=Avg('authors__age')).values() -[{'rating': 4.5, 'isbn': u'159059725', 'name': u'The Definitive Guide to Django: Web Development Done Right', 'pubdate': datetime.date(2007, 12, 6), 'price': Decimal("30..."), 'contact_id': 1, 'id': 1, 'publisher_id': 1, 'pages': 447, 'mean_age': 34.5}] +>>> [sorted(o.iteritems()) for o in Book.objects.filter(pk=1).annotate(mean_age=Avg('authors__age')).values()] +[[('contact_id', 1), ('id', 1), ('isbn', u'159059725'), ('mean_age', 34.5), ('name', u'The Definitive Guide to Django: Web Development Done Right'), ('pages', 447), ('price', Decimal("30...")), ('pubdate', datetime.date(2007, 12, 6)), ('publisher_id', 1), ('rating', 4.5)]] >>> Book.objects.filter(pk=1).annotate(mean_age=Avg('authors__age')).values('pk', 'isbn', 'mean_age') [{'pk': 1, 'isbn': u'159059725', 'mean_age': 34.5}] @@ -203,8 +203,8 @@ u'The Definitive Guide to Django: Web Development Done Right' # An empty values() call before annotating has the same effect as an # empty values() call after annotating ->>> Book.objects.filter(pk=1).values().annotate(mean_age=Avg('authors__age')) -[{'rating': 4.5, 'isbn': u'159059725', 'name': u'The Definitive Guide to Django: Web Development Done Right', 'pubdate': datetime.date(2007, 12, 6), 'price': Decimal("30..."), 'contact_id': 1, 'id': 1, 'publisher_id': 1, 'pages': 447, 'mean_age': 34.5}] +>>> [sorted(o.iteritems()) for o in Book.objects.filter(pk=1).values().annotate(mean_age=Avg('authors__age'))] +[[('contact_id', 1), ('id', 1), ('isbn', u'159059725'), ('mean_age', 34.5), ('name', u'The Definitive Guide to Django: Web Development Done Right'), ('pages', 447), ('price', Decimal("30...")), ('pubdate', datetime.date(2007, 12, 6)), ('publisher_id', 1), ('rating', 4.5)]] # Calling annotate() on a ValuesQuerySet annotates over the groups of # fields to be selected by the ValuesQuerySet. diff --git a/tests/modeltests/expressions/models.py b/tests/modeltests/expressions/models.py index 76006e10f0..f6292f5d9b 100644 --- a/tests/modeltests/expressions/models.py +++ b/tests/modeltests/expressions/models.py @@ -127,6 +127,6 @@ FieldError: Joined field references are not permitted in this query >>> acme.save() Traceback (most recent call last): ... -TypeError: int() argument must be a string or a number... +TypeError: ... """} diff --git a/tests/regressiontests/aggregation_regress/models.py b/tests/regressiontests/aggregation_regress/models.py index 7c51cd17a7..66a5ff7435 100644 --- a/tests/regressiontests/aggregation_regress/models.py +++ b/tests/regressiontests/aggregation_regress/models.py @@ -174,8 +174,8 @@ FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, conta {'number': 1132, 'select': 1132} # Regression for #10064: select_related() plays nice with aggregates ->>> Book.objects.select_related('publisher').annotate(num_authors=Count('authors')).values()[0] -{'rating': 4.0, 'isbn': u'013790395', 'name': u'Artificial Intelligence: A Modern Approach', 'pubdate': datetime.date(1995, 1, 15), 'price': Decimal("82.8..."), 'contact_id': 8, 'id': 5, 'num_authors': 2, 'publisher_id': 3, 'pages': 1132} +>>> sorted(Book.objects.select_related('publisher').annotate(num_authors=Count('authors')).values()[0].iteritems()) +[('contact_id', 8), ('id', 5), ('isbn', u'013790395'), ('name', u'Artificial Intelligence: A Modern Approach'), ('num_authors', 2), ('pages', 1132), ('price', Decimal("82.8...")), ('pubdate', datetime.date(1995, 1, 15)), ('publisher_id', 3), ('rating', 4.0)] # Regression for #10010: exclude on an aggregate field is correctly negated >>> len(Book.objects.annotate(num_authors=Count('authors'))) @@ -219,8 +219,8 @@ FieldError: Cannot resolve keyword 'foo' into field. Choices are: authors, conta >>> Book.objects.filter(id__in=[]).aggregate(num_authors=Count('authors'), avg_authors=Avg('authors'), max_authors=Max('authors'), max_price=Max('price'), max_rating=Max('rating')) {'max_authors': None, 'max_rating': None, 'num_authors': 0, 'avg_authors': None, 'max_price': None} ->>> Publisher.objects.filter(pk=5).annotate(num_authors=Count('book__authors'), avg_authors=Avg('book__authors'), max_authors=Max('book__authors'), max_price=Max('book__price'), max_rating=Max('book__rating')).values() -[{'max_authors': None, 'name': u"Jonno's House of Books", 'num_awards': 0, 'max_price': None, 'num_authors': 0, 'max_rating': None, 'id': 5, 'avg_authors': None}] +>>> list(Publisher.objects.filter(pk=5).annotate(num_authors=Count('book__authors'), avg_authors=Avg('book__authors'), max_authors=Max('book__authors'), max_price=Max('book__price'), max_rating=Max('book__rating')).values()) == [{'max_authors': None, 'name': u"Jonno's House of Books", 'num_awards': 0, 'max_price': None, 'num_authors': 0, 'max_rating': None, 'id': 5, 'avg_authors': None}] +True # Regression for #10113 - Fields mentioned in order_by() must be included in the GROUP BY. # This only becomes a problem when the order_by introduces a new join.