From 98b7800efee0304b6aaba5f5055656dfdba097e6 Mon Sep 17 00:00:00 2001 From: Konsta Vesterinen Date: Tue, 5 May 2015 13:10:54 +0300 Subject: [PATCH] Change translation hybrid expr Change translation hybrid expression to return the current translation if it exists and otherwise fallback to default translation. --- CHANGES.rst | 6 ++++++ sqlalchemy_utils/i18n.py | 7 ++++++- tests/test_translation_hybrid.py | 21 +++++++++++++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 355d16a..1da042c 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,12 @@ Changelog Here you can see the full list of changes between each SQLAlchemy-Utils release. +0.30.1 (2015-05-xx) +^^^^^^^^^^^^^^^^^^^ + +- Make translation_hybrid expression work the same way as SQLAlchemy-i18n translation expressions + + 0.30.0 (2015-04-15) ^^^^^^^^^^^^^^^^^^^ diff --git a/sqlalchemy_utils/i18n.py b/sqlalchemy_utils/i18n.py index daa414a..c9993d4 100644 --- a/sqlalchemy_utils/i18n.py +++ b/sqlalchemy_utils/i18n.py @@ -1,3 +1,4 @@ +import sqlalchemy as sa from sqlalchemy.ext.hybrid import hybrid_property from .exceptions import ImproperlyConfigured @@ -71,7 +72,11 @@ class TranslationHybrid(object): return setter def expr_factory(self, attr): - return lambda cls: attr + def expr(cls): + current_locale = self.cast_locale(cls, self.current_locale) + default_locale = self.cast_locale(cls, self.default_locale) + return sa.func.coalesce(attr[current_locale], attr[default_locale]) + return expr def __call__(self, attr): return hybrid_property( diff --git a/tests/test_translation_hybrid.py b/tests/test_translation_hybrid.py index 66c5116..5b6f96f 100644 --- a/tests/test_translation_hybrid.py +++ b/tests/test_translation_hybrid.py @@ -1,4 +1,5 @@ import sqlalchemy as sa +from pytest import mark from sqlalchemy.dialects.postgresql import HSTORE from sqlalchemy_utils import TranslationHybrid @@ -26,9 +27,6 @@ class TestTranslationHybrid(TestCase): city = self.City(name='Helsinki') assert city.name_translations['fi'] == 'Helsinki' - def test_hybrid_as_expression(self): - assert self.City.name == self.City.name_translations - def test_if_no_translation_exists_returns_none(self): city = self.City() assert city.name is None @@ -52,11 +50,18 @@ class TestTranslationHybrid(TestCase): assert city.name == 'Helsinki' - def test_hybrid_as_an_expression(self): - city = self.City(name_translations={'en': 'Helsinki'}) + @mark.parametrize( + ('name_translations', 'name'), + ( + ({'fi': 'Helsinki', 'en': 'Helsing'}, 'Helsinki'), + ({'en': 'Helsinki'}, 'Helsinki'), + ({'fi': 'Helsinki'}, 'Helsinki'), + ({}, None), + ) + ) + def test_hybrid_as_an_expression(self, name_translations, name): + city = self.City(name_translations=name_translations) self.session.add(city) self.session.commit() - assert city == self.session.query(self.City).filter( - self.City.name['en'] == 'Helsinki' - ).first() + assert self.session.query(self.City.name).scalar() == name