diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index cecae216c0..0a34f807b3 100644 --- a/django/contrib/admin/filters.py +++ b/django/contrib/admin/filters.py @@ -8,13 +8,13 @@ certain test -- e.g. being a DateField or ForeignKey. import datetime from django.db import models -from django.core.exceptions import ImproperlyConfigured +from django.core.exceptions import ImproperlyConfigured, ValidationError from django.utils.encoding import smart_text from django.utils.translation import ugettext_lazy as _ from django.utils import timezone - from django.contrib.admin.util import (get_model_from_relation, reverse_field_path, get_limit_choices_to_from_path, prepare_lookup_value) +from django.contrib.admin.options import IncorrectLookupParameters class ListFilter(object): title = None # Human-readable title to appear in the right sidebar. @@ -129,7 +129,10 @@ class FieldListFilter(ListFilter): return True def queryset(self, request, queryset): - return queryset.filter(**self.used_parameters) + try: + return queryset.filter(**self.used_parameters) + except ValidationError as e: + raise IncorrectLookupParameters(e) @classmethod def register(cls, test, list_filter_class, take_priority=False): diff --git a/django/contrib/auth/tests/views.py b/django/contrib/auth/tests/views.py index 635ebf5436..d7d3e441a9 100644 --- a/django/contrib/auth/tests/views.py +++ b/django/contrib/auth/tests/views.py @@ -1,7 +1,7 @@ import os import re -from django.conf import settings +from django.conf import global_settings, settings from django.contrib.sites.models import Site, RequestSite from django.contrib.auth.models import User from django.core import mail @@ -24,7 +24,8 @@ from django.contrib.auth.tests.utils import skipIfCustomUser ('en', 'English'), ), LANGUAGE_CODE='en', - TEMPLATE_DIRS = ( + TEMPLATE_LOADERS=global_settings.TEMPLATE_LOADERS, + TEMPLATE_DIRS=( os.path.join(os.path.dirname(__file__), 'templates'), ), USE_TZ=False, diff --git a/django/test/signals.py b/django/test/signals.py index 5b0a9a19ca..d140304f1d 100644 --- a/django/test/signals.py +++ b/django/test/signals.py @@ -51,6 +51,13 @@ def clear_context_processors_cache(**kwargs): context._standard_context_processors = None +@receiver(setting_changed) +def clear_template_loaders_cache(**kwargs): + if kwargs['setting'] == 'TEMPLATE_LOADERS': + from django.template import loader + loader.template_source_loaders = None + + @receiver(setting_changed) def clear_serializers_cache(**kwargs): if kwargs['setting'] == 'SERIALIZATION_MODULES': diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt index 80b3158f01..8ec7cfc791 100644 --- a/docs/ref/models/querysets.txt +++ b/docs/ref/models/querysets.txt @@ -1050,7 +1050,7 @@ defer In some complex data-modeling situations, your models might contain a lot of fields, some of which could contain a lot of data (for example, text fields), or require expensive processing to convert them to Python objects. If you are -using the results of a queryset in some situation where you know you don't know +using the results of a queryset in some situation where you don't know if you need those particular fields when you initially fetch the data, you can tell Django not to retrieve them from the database. diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt index b54a9475ae..28baf87522 100644 --- a/docs/topics/logging.txt +++ b/docs/topics/logging.txt @@ -255,12 +255,12 @@ complex logging setup, configured using :meth:`logging.dictConfig`:: }, 'handlers': { 'null': { - 'level':'DEBUG', - 'class':'django.utils.log.NullHandler', + 'level': 'DEBUG', + 'class': 'django.utils.log.NullHandler', }, 'console':{ - 'level':'DEBUG', - 'class':'logging.StreamHandler', + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', 'formatter': 'simple' }, 'mail_admins': { @@ -271,9 +271,9 @@ complex logging setup, configured using :meth:`logging.dictConfig`:: }, 'loggers': { 'django': { - 'handlers':['null'], + 'handlers': ['null'], 'propagate': True, - 'level':'INFO', + 'level': 'INFO', }, 'django.request': { 'handlers': ['mail_admins'], diff --git a/tests/regressiontests/admin_views/admin.py b/tests/regressiontests/admin_views/admin.py index fe291ebfb8..a5476e9eb7 100644 --- a/tests/regressiontests/admin_views/admin.py +++ b/tests/regressiontests/admin_views/admin.py @@ -130,7 +130,7 @@ class CustomArticleAdmin(admin.ModelAdmin): class ThingAdmin(admin.ModelAdmin): - list_filter = ('color__warm', 'color__value') + list_filter = ('color__warm', 'color__value', 'pub_date',) class InquisitionAdmin(admin.ModelAdmin): diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py index 2c935c05a5..2b143004d9 100644 --- a/tests/regressiontests/admin_views/models.py +++ b/tests/regressiontests/admin_views/models.py @@ -128,6 +128,7 @@ class Color2(Color): class Thing(models.Model): title = models.CharField(max_length=20) color = models.ForeignKey(Color, limit_choices_to={'warm': True}) + pub_date = models.DateField(blank=True, null=True) def __str__(self): return self.title diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py index dea28b1fed..b0723280f7 100644 --- a/tests/regressiontests/admin_views/tests.py +++ b/tests/regressiontests/admin_views/tests.py @@ -437,6 +437,10 @@ class AdminViewBasicTest(TestCase): response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'color__id__exact': 'StringNotInteger!'}) self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + # Regression test for #18530 + response = self.client.get('/test_admin/%s/admin_views/thing/' % self.urlbit, {'pub_date__gte': 'foo'}) + self.assertRedirects(response, '/test_admin/%s/admin_views/thing/?e=1' % self.urlbit) + def testIsNullLookups(self): """Ensure is_null is handled correctly.""" Article.objects.create(title="I Could Go Anywhere", content="Versatile", date=datetime.datetime.now()) diff --git a/tests/regressiontests/views/tests/debug.py b/tests/regressiontests/views/tests/debug.py index 56383ac196..8592b07efe 100644 --- a/tests/regressiontests/views/tests/debug.py +++ b/tests/regressiontests/views/tests/debug.py @@ -1,36 +1,27 @@ -from __future__ import absolute_import +from __future__ import absolute_import, unicode_literals import inspect import os import sys from django.conf import settings -from django.core.files.uploadedfile import SimpleUploadedFile -from django.test import TestCase, RequestFactory -from django.test.utils import (setup_test_template_loader, - restore_template_loaders) -from django.core.urlresolvers import reverse -from django.views.debug import ExceptionReporter from django.core import mail +from django.core.files.uploadedfile import SimpleUploadedFile +from django.core.urlresolvers import reverse +from django.test import TestCase, RequestFactory +from django.test.utils import (override_settings, setup_test_template_loader, + restore_template_loaders) +from django.views.debug import ExceptionReporter from .. import BrokenException, except_args from ..views import (sensitive_view, non_sensitive_view, paranoid_view, custom_exception_reporter_filter_view, sensitive_method_view) +@override_settings(DEBUG=True, TEMPLATE_DEBUG=True) class DebugViewTests(TestCase): urls = "regressiontests.views.urls" - def setUp(self): - self.old_debug = settings.DEBUG - settings.DEBUG = True - self.old_template_debug = settings.TEMPLATE_DEBUG - settings.TEMPLATE_DEBUG = True - - def tearDown(self): - settings.DEBUG = self.old_debug - settings.TEMPLATE_DEBUG = self.old_template_debug - def test_files(self): response = self.client.get('/raises/') self.assertEqual(response.status_code, 500)