Add filters conf, add deprecation warnings

This commit is contained in:
Ryan P Kilby 2016-09-14 16:21:38 -04:00
parent 83e035860d
commit 58114084c4
5 changed files with 204 additions and 4 deletions

106
django_filters/conf.py Normal file
View File

@ -0,0 +1,106 @@
from django.conf import settings as dj_settings
from django.core.signals import setting_changed
from django.utils.translation import ugettext_lazy as _
from .utils import deprecate
DEFAULTS = {
'HELP_TEXT_FILTER': True,
'HELP_TEXT_EXCLUDE': True,
'VERBOSE_LOOKUPS': {
# transforms don't need to be verbose, since their expressions are chained
'date': _('date'),
'year': _('year'),
'month': _('month'),
'day': _('day'),
'week_day': _('week day'),
'hour': _('hour'),
'minute': _('minute'),
'second': _('second'),
# standard lookups
'exact': _(''),
'iexact': _(''),
'contains': _('contains'),
'icontains': _('contains'),
'in': _('is in'),
'gt': _('is greater than'),
'gte': _('is greater than or equal to'),
'lt': _('is less than'),
'lte': _('is less than or equal to'),
'startswith': _('starts with'),
'istartswith': _('starts with'),
'endswith': _('ends with'),
'iendswith': _('ends with'),
'range': _('is in range'),
'isnull': _(''),
'regex': _('matches regex'),
'iregex': _('matches regex'),
'search': _('search'),
# postgres lookups
'contained_by': _('is contained by'),
'overlap': _('overlaps'),
'has_key': _('has key'),
'has_keys': _('has keys'),
'has_any_keys': _('has any keys'),
'trigram_similar': _('search'),
},
}
DEPRECATED_SETTINGS = [
'HELP_TEXT_FILTER',
'HELP_TEXT_EXCLUDE'
]
class Settings(object):
def __init__(self):
for setting in DEFAULTS:
value = self.get_setting(setting)
setattr(self, setting, value)
def VERBOSE_LOOKUPS():
"""
VERBOSE_LOOKUPS accepts a dictionary of {terms: verbose expressions}
or a zero-argument callable that returns a dictionary.
"""
def fget(self):
if callable(self._VERBOSE_LOOKUPS):
self._VERBOSE_LOOKUPS = self._VERBOSE_LOOKUPS()
return self._VERBOSE_LOOKUPS
def fset(self, value):
self._VERBOSE_LOOKUPS = value
return locals()
VERBOSE_LOOKUPS = property(**VERBOSE_LOOKUPS())
def get_setting(self, setting):
django_setting = 'FILTERS_%s' % setting
if setting in DEPRECATED_SETTINGS and hasattr(dj_settings, django_setting):
deprecate("The '%s' setting has been deprecated." % django_setting)
return getattr(dj_settings, django_setting, DEFAULTS[setting])
def change_setting(self, setting, value, enter, **kwargs):
if not setting.startswith('FILTERS_'):
return
setting = setting[8:] # strip 'FILTERS_'
# ensure a valid app setting is being overridden
if setting not in DEFAULTS:
return
# if exiting, refetch the value from settings.
value = value if enter else self.get_setting(setting)
setattr(self, setting, value)
settings = Settings()
setting_changed.connect(settings.change_setting)

View File

@ -9,12 +9,12 @@ from django import forms
from django.db.models import Q
from django.db.models.sql.constants import QUERY_TERMS
from django.db.models.constants import LOOKUP_SEP
from django.conf import settings
from django.utils import six
from django.utils.itercompat import is_iterable
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from .conf import settings
from .fields import (
Lookup, LookupTypeField, BaseCSVField, BaseRangeField, RangeField,
DateRangeField, DateTimeRangeField, TimeRangeField, IsoDateTimeField
@ -132,9 +132,9 @@ class Filter(object):
if not hasattr(self, '_field'):
help_text = self.extra.pop('help_text', None)
if help_text is None:
if self.exclude and getattr(settings, "FILTERS_HELP_TEXT_EXCLUDE", True):
if self.exclude and settings.HELP_TEXT_EXCLUDE:
help_text = _('This is an exclusion filter')
elif not self.exclude and getattr(settings, "FILTERS_HELP_TEXT_FILTER", True):
elif not self.exclude and settings.HELP_TEXT_FILTER:
help_text = _('Filter')
else:
help_text = ''

View File

@ -26,3 +26,9 @@ TEMPLATES = [{
MIDDLEWARE = []
# help verify that DEFAULTS is importable from conf.
def FILTERS_VERBOSE_LOOKUPS():
from django_filters.conf import DEFAULTS
return DEFAULTS['VERBOSE_LOOKUPS']

64
tests/test_conf.py Normal file
View File

@ -0,0 +1,64 @@
from django.test import TestCase, override_settings
from django_filters.conf import settings
class DefaultSettingsTests(TestCase):
def test_verbose_loookups(self):
self.assertIsInstance(settings.VERBOSE_LOOKUPS, dict)
self.assertIn('exact', settings.VERBOSE_LOOKUPS)
def test_help_text_filter(self):
self.assertTrue(settings.HELP_TEXT_FILTER)
def test_help_text_exclude(self):
self.assertTrue(settings.HELP_TEXT_EXCLUDE)
class OverrideSettingsTests(TestCase):
def test_attribute_override(self):
self.assertIsInstance(settings.VERBOSE_LOOKUPS, dict)
original = settings.VERBOSE_LOOKUPS
with override_settings(FILTERS_VERBOSE_LOOKUPS=None):
self.assertIsNone(settings.VERBOSE_LOOKUPS)
self.assertIs(settings.VERBOSE_LOOKUPS, original)
def test_missing_attribute_override(self):
# ensure that changed setting behaves correctly when
# not originally present in the user's settings.
from django.conf import settings as dj_settings
self.assertFalse(hasattr(dj_settings, 'FILTERS_HELP_TEXT_FILTER'))
# Default value
self.assertTrue(settings.HELP_TEXT_FILTER)
with override_settings(FILTERS_HELP_TEXT_FILTER=None):
self.assertIsNone(settings.HELP_TEXT_FILTER)
# Revert to default
self.assertTrue(settings.HELP_TEXT_FILTER)
def test_non_filters_setting(self):
self.assertFalse(hasattr(settings, 'USE_TZ'))
with override_settings(USE_TZ=False):
self.assertFalse(hasattr(settings, 'USE_TZ'))
self.assertFalse(hasattr(settings, 'USE_TZ'))
def test_non_existent_setting(self):
self.assertFalse(hasattr(settings, 'FILTERS_FOOBAR'))
self.assertFalse(hasattr(settings, 'FOOBAR'))
with override_settings(FILTERS_FOOBAR='blah'):
self.assertFalse(hasattr(settings, 'FILTERS_FOOBAR'))
self.assertFalse(hasattr(settings, 'FOOBAR'))
self.assertFalse(hasattr(settings, 'FILTERS_FOOBAR'))
self.assertFalse(hasattr(settings, 'FOOBAR'))

View File

@ -3,9 +3,10 @@ import functools
import warnings
import mock
from django.core.exceptions import ValidationError
from django.test import TestCase
from django.test import TestCase, override_settings
from django_filters import FilterSet
from django_filters.conf import Settings
from django_filters.filters import Filter, CharFilter, MethodFilter
from django_filters.filterset import STRICTNESS
from .models import User
@ -692,3 +693,26 @@ class DeprecatedOrderingFormTests(TestCase):
f = F().form
self.assertEqual(
f.fields['o'].choices, [('status', 'Current status')])
class DeprecatedSettingsTests(TestCase):
def test_filter_help_text(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
with override_settings(FILTERS_HELP_TEXT_FILTER=False):
Settings()
self.assertEqual(len(w), 1)
self.assertIn("The 'FILTERS_HELP_TEXT_FILTER' setting has been deprecated.", str(w[0].message))
def test_exclude_help_text(self):
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
with override_settings(FILTERS_HELP_TEXT_EXCLUDE=False):
Settings()
self.assertEqual(len(w), 1)
self.assertIn("The 'FILTERS_HELP_TEXT_EXCLUDE' setting has been deprecated.", str(w[0].message))