From 33d23ce14f2e5e1d86e26977b8fca21579305f14 Mon Sep 17 00:00:00 2001 From: Konsta Vesterinen Date: Thu, 24 Oct 2013 15:14:15 +0300 Subject: [PATCH] Added docs for ChoiceType --- CHANGES.rst | 6 +++ docs/index.rst | 84 +++++++++++++++++++++++------ sqlalchemy_utils/types/choice.py | 4 +- sqlalchemy_utils/types/slug_type.py | 0 tests/types/test_choice_type.py | 9 ++-- 5 files changed, 83 insertions(+), 20 deletions(-) delete mode 100644 sqlalchemy_utils/types/slug_type.py diff --git a/CHANGES.rst b/CHANGES.rst index de36a88..d494a61 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.19.0 (2013-10-24) +^^^^^^^^^^^^^^^^^^^ + +- Added ChoiceType + + 0.18.0 (2013-10-24) ^^^^^^^^^^^^^^^^^^^ diff --git a/docs/index.rst b/docs/index.rst index f0330f7..17c86ac 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -37,9 +37,9 @@ Example class Document(Base): __tablename__ = 'player' - id = db.Column(db.Integer, autoincrement=True) - name = db.Column(db.Unicode(50)) - background_color = db.Column(ColorType) + id = sa.Column(sa.Integer, autoincrement=True) + name = sa.Column(sa.Unicode(50)) + background_color = sa.Column(ColorType) document = Document() @@ -55,6 +55,58 @@ Data types SQLAlchemy-Utils provides various new data types for SQLAlchemy. +ChoiceType +^^^^^^^^^^ + +ChoiceType offers way of having fixed set of choices for given column. Columns with ChoiceTypes are automatically coerced to Choice objects. + + +:: + + + class User(self.Base): + TYPES = [ + (u'admin', u'Admin'), + (u'regular-user', u'Regular user') + ] + + __tablename__ = 'user' + id = sa.Column(sa.Integer, primary_key=True) + name = sa.Column + type = sa.Column(ChoiceType(TYPES)) + + + user = User(type=u'admin') + user.type # Choice(type='admin', value=u'Admin') + + + +ChoiceType is very useful when the rendered values change based on user's locale: + +:: + + from babel import lazy_gettext as _ + + + class User(self.Base): + TYPES = [ + (u'admin', _(u'Admin')), + (u'regular-user', _(u'Regular user')) + ] + + __tablename__ = 'user' + id = sa.Column(sa.Integer, primary_key=True) + name = sa.Column + type = sa.Column(ChoiceType(TYPES)) + + + user = User(type=u'admin') + user.type # Choice(type='admin', value=u'Admin') + + + + + ColorType ^^^^^^^^^ @@ -70,9 +122,9 @@ ColorType saves Color objects as strings on the way in and converts them back to class Document(Base): __tablename__ = 'document' - id = db.Column(db.Integer, autoincrement=True) - name = db.Column(db.Unicode(50)) - background_color = db.Column(ColorType) + id = sa.Column(sa.Integer, autoincrement=True) + name = sa.Column(sa.Unicode(50)) + background_color = sa.Column(ColorType) document = Document() @@ -110,9 +162,9 @@ In order to use LocaleType you need to install Babel_ first. class User(Base): __tablename__ = 'user' - id = db.Column(db.Integer, autoincrement=True) - name = db.Column(db.Unicode(50)) - locale = db.Column(LocaleType) + id = sa.Column(sa.Integer, autoincrement=True) + name = sa.Column(sa.Unicode(50)) + locale = sa.Column(LocaleType) user = User() @@ -143,9 +195,9 @@ Example :: class Event(Base): __tablename__ = 'user' - id = db.Column(db.Integer, autoincrement=True) - name = db.Column(db.Unicode(255)) - estimated_number_of_persons = db.Column(NumberRangeType) + id = sa.Column(sa.Integer, autoincrement=True) + name = sa.Column(sa.Unicode(255)) + estimated_number_of_persons = sa.Column(NumberRangeType) party = Event(name=u'party') @@ -190,8 +242,8 @@ Example :: class User(Base): __tablename__ = 'user' - id = db.Column(db.Integer, autoincrement=True) - hobbies = db.Column(ScalarListType()) + id = sa.Column(sa.Integer, autoincrement=True) + hobbies = sa.Column(ScalarListType()) user = User() @@ -209,8 +261,8 @@ You can easily set up integer lists too: class Player(Base): __tablename__ = 'player' - id = db.Column(db.Integer, autoincrement=True) - points = db.Column(ScalarListType(int)) + id = sa.Column(sa.Integer, autoincrement=True) + points = sa.Column(ScalarListType(int)) player = Player() diff --git a/sqlalchemy_utils/types/choice.py b/sqlalchemy_utils/types/choice.py index c32aacb..124973b 100644 --- a/sqlalchemy_utils/types/choice.py +++ b/sqlalchemy_utils/types/choice.py @@ -30,13 +30,15 @@ class Choice(object): class ChoiceType(types.TypeDecorator, ScalarCoercible): impl = types.Unicode(255) - def __init__(self, choices): + def __init__(self, choices, impl=None): if not choices: raise ImproperlyConfigured( 'ChoiceType needs list of choices defined.' ) self.choices = choices self.choices_dict = dict(choices) + if impl: + self.impl = impl def _coerce(self, value): if value is None: diff --git a/sqlalchemy_utils/types/slug_type.py b/sqlalchemy_utils/types/slug_type.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/types/test_choice_type.py b/tests/types/test_choice_type.py index 7c78dd5..6f727b4 100644 --- a/tests/types/test_choice_type.py +++ b/tests/types/test_choice_type.py @@ -5,9 +5,6 @@ from tests import TestCase class TestChoice(object): - # def test_init(self): - # assert Choice(1, 1) == Choice(Choice(1, 1)) - def test_equality_operator(self): assert Choice(1, 1) == 1 assert 1 == Choice(1, 1) @@ -54,3 +51,9 @@ class TestChoiceType(TestCase): def test_throws_exception_if_no_choices_given(self): with raises(ImproperlyConfigured): ChoiceType([]) + + +class TestChoiceTypeWithCustomUnderlyingType(TestCase): + def test_init_type(self): + type_ = ChoiceType([(1, u'something')], impl=sa.Integer) + assert type_.impl == sa.Integer