From 7ff0506f27fe882a24f2e540b402e1df592ef2d3 Mon Sep 17 00:00:00 2001 From: wrwrwr Date: Thu, 24 Jan 2013 18:34:09 +0100 Subject: [PATCH 1/3] Context manager for temporarily switching fallbacks on or off. --- modeltranslation/fields.py | 2 +- modeltranslation/settings.py | 1 + modeltranslation/utils.py | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/modeltranslation/fields.py b/modeltranslation/fields.py index b873edc..91e0f69 100644 --- a/modeltranslation/fields.py +++ b/modeltranslation/fields.py @@ -156,7 +156,7 @@ class TranslationFieldDescriptor(object): # Here we check only for None and '', because e.g. 0 should not fall back. if val is not None and val != '': return val - if self.fallback_value is None: + if self.fallback_value is None or not mt_settings.ENABLE_FALLBACKS: return self.field.get_default() else: return self.fallback_value diff --git a/modeltranslation/settings.py b/modeltranslation/settings.py index 19937a2..1a92c77 100644 --- a/modeltranslation/settings.py +++ b/modeltranslation/settings.py @@ -51,3 +51,4 @@ for key, value in FALLBACK_LANGUAGES.iteritems(): if lang not in AVAILABLE_LANGUAGES: raise ImproperlyConfigured( 'MODELTRANSLATION_FALLBACK_LANGUAGES: "%s" not in LANGUAGES setting.' % lang) +ENABLE_FALLBACKS = getattr(settings, 'MODELTRANSLATION_ENABLE_FALLBACKS', True) diff --git a/modeltranslation/utils.py b/modeltranslation/utils.py index d3049a4..27eb9b1 100644 --- a/modeltranslation/utils.py +++ b/modeltranslation/utils.py @@ -90,6 +90,8 @@ def resolution_order(lang, override=None): First is always the parameter language, later are fallback languages. Override parameter has priority over FALLBACK_LANGUAGES. """ + if not settings.ENABLE_FALLBACKS: + return (lang,) if override is None: override = {} fallback_for_lang = override.get(lang, settings.FALLBACK_LANGUAGES.get(lang, ())) @@ -123,3 +125,25 @@ def auto_populate(mode='all'): yield finally: settings.AUTO_POPULATE = current_population_mode + + +@contextmanager +def fallbacks(enable=True): + """ + Temporarily switch all language fallbacks on or off. + + Example: + + with fallbacks(False): + lang_has_slug = bool(self.slug) + + May be used to enable fallbacks just when they're needed saving on some + processing or check if there is a value for the current language (not + knowing the language) + """ + current_enable_fallbacks = settings.ENABLE_FALLBACKS + settings.ENABLE_FALLBACKS = enable + try: + yield + finally: + settings.ENABLE_FALLBACKS = current_enable_fallbacks From 3a4ec607137f0f9d1d613fd2568291a3db53dab9 Mon Sep 17 00:00:00 2001 From: wrwrwr Date: Sun, 24 Feb 2013 10:04:22 +0100 Subject: [PATCH 2/3] Test and docs for the new fallbacks toggle. --- docs/modeltranslation/usage.rst | 5 +++++ modeltranslation/tests/__init__.py | 18 +++++++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/docs/modeltranslation/usage.rst b/docs/modeltranslation/usage.rst index 9310fd3..b85810c 100644 --- a/docs/modeltranslation/usage.rst +++ b/docs/modeltranslation/usage.rst @@ -246,6 +246,11 @@ What is more, fallback languages order can be overridden per model, using ``Tran Dict syntax is only allowed there. +Even more, all fallbacks may be switched on or off for just some exceptional block of code using:: + + with fallbacks(False): + // work with values for the active language only + Fallback values *************** diff --git a/modeltranslation/tests/__init__.py b/modeltranslation/tests/__init__.py index d9dc880..4201a81 100644 --- a/modeltranslation/tests/__init__.py +++ b/modeltranslation/tests/__init__.py @@ -32,7 +32,7 @@ from modeltranslation.tests.translation import (FallbackModel2TranslationOptions FieldInheritanceETranslationOptions) from modeltranslation.tests.test_settings import TEST_SETTINGS from modeltranslation.utils import (build_css_class, build_localized_fieldname, - auto_populate) + auto_populate, fallbacks) try: from django.test.utils import override_settings @@ -514,6 +514,22 @@ class FallbackTests(ModeltranslationTestBase): n.title_en = None self.assertEqual(n.title, '') # if all fallbacks fail, return field.get_default() + def test_fallbacks_toggle(self): + with reload_override_settings(MODELTRANSLATION_FALLBACK_LANGUAGES=self.test_fallback): + m = models.TestModel(title='foo') + with fallbacks(True): + self.assertEqual(m.title_de, 'foo') + self.assertEqual(m.title_en, None) + self.assertEqual(m.title, 'foo') + with override('en'): + self.assertEqual(m.title, 'foo') + with fallbacks(False): + self.assertEqual(m.title_de, 'foo') + self.assertEqual(m.title_en, None) + self.assertEqual(m.title, 'foo') + with override('en'): + self.assertEqual(m.title, '') # '' is the default + class FileFieldsTest(ModeltranslationTestBase): test_media_root = TEST_SETTINGS['MEDIA_ROOT'] From c7ace45dff31f7bb5da6dd9b491f6ebdcd9e9a0a Mon Sep 17 00:00:00 2001 From: wrwrwr Date: Sun, 24 Feb 2013 12:17:17 +0100 Subject: [PATCH 3/3] Use the right comment syntax in docs. --- docs/modeltranslation/usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/modeltranslation/usage.rst b/docs/modeltranslation/usage.rst index b85810c..ef29dfd 100644 --- a/docs/modeltranslation/usage.rst +++ b/docs/modeltranslation/usage.rst @@ -249,7 +249,7 @@ Dict syntax is only allowed there. Even more, all fallbacks may be switched on or off for just some exceptional block of code using:: with fallbacks(False): - // work with values for the active language only + # Work with values for the active language only Fallback values ***************