Fixed #22057 -- Ensured reverse_lazy can be used in settings

And without causing a circular import. Thanks Akis Kesoglou for
the report.
This commit is contained in:
Claude Paroz 2014-02-18 10:19:04 +01:00
parent faf6a911ad
commit 45edb9d235
3 changed files with 35 additions and 8 deletions

View File

@ -5,16 +5,12 @@ import copy
from django.db.models.fields import IntegerField, FloatField from django.db.models.fields import IntegerField, FloatField
from django.db.models.lookups import RegisterLookupMixin from django.db.models.lookups import RegisterLookupMixin
from django.utils.functional import cached_property
__all__ = ['Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance'] __all__ = ['Aggregate', 'Avg', 'Count', 'Max', 'Min', 'StdDev', 'Sum', 'Variance']
# Fake fields used to identify aggregate types in data-conversion operations.
ordinal_aggregate_field = IntegerField()
computed_aggregate_field = FloatField()
class Aggregate(RegisterLookupMixin): class Aggregate(RegisterLookupMixin):
""" """
Default SQL Aggregate. Default SQL Aggregate.
@ -61,14 +57,23 @@ class Aggregate(RegisterLookupMixin):
while tmp and isinstance(tmp, Aggregate): while tmp and isinstance(tmp, Aggregate):
if getattr(tmp, 'is_ordinal', False): if getattr(tmp, 'is_ordinal', False):
tmp = ordinal_aggregate_field tmp = self._ordinal_aggregate_field
elif getattr(tmp, 'is_computed', False): elif getattr(tmp, 'is_computed', False):
tmp = computed_aggregate_field tmp = self._computed_aggregate_field
else: else:
tmp = tmp.source tmp = tmp.source
self.field = tmp self.field = tmp
# Two fake fields used to identify aggregate types in data-conversion operations.
@cached_property
def _ordinal_aggregate_field(self):
return IntegerField()
@cached_property
def _computed_aggregate_field(self):
return FloatField()
def relabeled_clone(self, change_map): def relabeled_clone(self, change_map):
clone = copy.copy(self) clone = copy.copy(self)
if isinstance(self.col, (list, tuple)): if isinstance(self.col, (list, tuple)):

View File

@ -40,7 +40,7 @@ custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates
class AdminScriptTestCase(unittest.TestCase): class AdminScriptTestCase(unittest.TestCase):
def write_settings(self, filename, apps=None, is_dir=False, sdict=None): def write_settings(self, filename, apps=None, is_dir=False, sdict=None, extra=None):
if is_dir: if is_dir:
settings_dir = os.path.join(test_dir, filename) settings_dir = os.path.join(test_dir, filename)
os.mkdir(settings_dir) os.mkdir(settings_dir)
@ -51,6 +51,8 @@ class AdminScriptTestCase(unittest.TestCase):
with open(settings_file_path, 'w') as settings_file: with open(settings_file_path, 'w') as settings_file:
settings_file.write('# -*- coding: utf-8 -*\n') settings_file.write('# -*- coding: utf-8 -*\n')
settings_file.write('# Settings file automatically generated by admin_scripts test case\n') settings_file.write('# Settings file automatically generated by admin_scripts test case\n')
if extra:
settings_file.write("%s\n" % extra)
exports = [ exports = [
'DATABASES', 'DATABASES',
'ROOT_URLCONF', 'ROOT_URLCONF',

View File

@ -15,6 +15,8 @@ from django.shortcuts import redirect
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from django.utils import six from django.utils import six
from admin_scripts.tests import AdminScriptTestCase
from . import urlconf_outer, middleware, views from . import urlconf_outer, middleware, views
from .views import empty_view from .views import empty_view
@ -301,6 +303,24 @@ class ReverseLazyTest(TestCase):
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
class ReverseLazySettingsTest(AdminScriptTestCase):
"""
Test that reverse_lazy can be used in settings without causing a circular
import error.
"""
def setUp(self):
self.write_settings('settings.py', extra="""
from django.core.urlresolvers import reverse_lazy
LOGIN_URL = reverse_lazy('login')""")
def tearDown(self):
self.remove_settings('settings.py')
def test_lazy_in_settings(self):
out, err = self.run_manage(['test'])
self.assertOutput(err, "Ran 0 tests")
class ReverseShortcutTests(TestCase): class ReverseShortcutTests(TestCase):
urls = 'urlpatterns_reverse.urls' urls = 'urlpatterns_reverse.urls'