From 07853d70b75017736d03b977ffabeb48935416bc Mon Sep 17 00:00:00 2001 From: beenje Date: Sat, 2 Sep 2017 21:20:24 +0200 Subject: [PATCH] Add support for postgres CITEXT type citext is a case-insensitive character string type. See https://www.postgresql.org/docs/current/static/citext.html --- flask_admin/contrib/sqla/form.py | 4 +-- flask_admin/tests/sqla/test_postgres.py | 37 +++++++++++++++++++++++++ requirements-dev.txt | 1 + 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/flask_admin/contrib/sqla/form.py b/flask_admin/contrib/sqla/form.py index a2640b46e..49f3ebf84 100644 --- a/flask_admin/contrib/sqla/form.py +++ b/flask_admin/contrib/sqla/form.py @@ -264,7 +264,7 @@ def convert(self, model, mapper, name, prop, field_args, hidden_pk): @classmethod def _string_common(cls, column, field_args, **extra): - if isinstance(column.type.length, int) and column.type.length: + if hasattr(column.type, 'length') and isinstance(column.type.length, int) and column.type.length: field_args['validators'].append(validators.Length(max=column.type.length)) @converts('String') # includes VARCHAR, CHAR, and Unicode @@ -290,7 +290,7 @@ def conv_String(self, column, field_args, **extra): self._string_common(column=column, field_args=field_args, **extra) return fields.StringField(**field_args) - @converts('Text', 'LargeBinary', 'Binary') # includes UnicodeText + @converts('Text', 'LargeBinary', 'Binary', 'CIText') # includes UnicodeText def conv_Text(self, field_args, **extra): self._string_common(field_args=field_args, **extra) return fields.TextAreaField(**field_args) diff --git a/flask_admin/tests/sqla/test_postgres.py b/flask_admin/tests/sqla/test_postgres.py index 9a845fcb1..c8085bd04 100644 --- a/flask_admin/tests/sqla/test_postgres.py +++ b/flask_admin/tests/sqla/test_postgres.py @@ -4,6 +4,7 @@ from .test_basic import CustomModelView from sqlalchemy.dialects.postgresql import HSTORE, JSON +from citext import CIText def test_hstore(): @@ -75,3 +76,39 @@ class JSONModel(db.Model): data = rv.data.decode('utf-8') ok_('json_test' in data) ok_('>{"test_key1": "test_value1"}<' in data) + + +def test_citext(): + app, db, admin = setup_postgres() + + class CITextModel(db.Model): + id = db.Column(db.Integer, primary_key=True, autoincrement=True) + citext_test = db.Column(CIText) + + db.engine.execute('CREATE EXTENSION IF NOT EXISTS citext') + db.create_all() + + view = CustomModelView(CITextModel, db.session) + admin.add_view(view) + + client = app.test_client() + + rv = client.get('/admin/citextmodel/') + eq_(rv.status_code, 200) + + rv = client.post('/admin/citextmodel/new/', data={ + 'citext_test': 'Foo', + }) + eq_(rv.status_code, 302) + + rv = client.get('/admin/citextmodel/') + eq_(rv.status_code, 200) + data = rv.data.decode('utf-8') + ok_('citext_test' in data) + ok_('Foo' in data) + + rv = client.get('/admin/citextmodel/edit/?id=1') + eq_(rv.status_code, 200) + data = rv.data.decode('utf-8') + ok_('name="citext_test"' in data) + ok_('>Foo<' in data) diff --git a/requirements-dev.txt b/requirements-dev.txt index d46652abc..ea1e9a5e0 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -14,3 +14,4 @@ psycopg2 nose coveralls pylint +sqlalchemy-citext