Coverage for gws-app/gws/plugin/model_field/text/__init__.py: 100%
33 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-23 20:06 +0200
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-23 20:06 +0200
1"""Text field.
3A scalar field for strings. Without a configured widget, the field uses an
4``input`` widget.
6With ``textSearch``, the field takes part in keyword searches of database
7models. The keyword is compared with the column value cast to a string:
9- ``exact``: the value equals the keyword,
10- ``any``, ``begin``, ``end``: the keyword occurs anywhere, at the start or at
11 the end of the value; ``%`` and ``_`` in the keyword are matched literally,
12- ``like``: the keyword is used as an SQL ``LIKE`` pattern as is.
14The pattern match is case-insensitive (``ILIKE``) unless ``caseSensitive`` is set.
15Keywords shorter than ``minLength`` are ignored.
17Example::
19 fields+ {
20 name "name"
21 type "text"
22 textSearch { type "begin" minLength 2 }
23 }
24"""
26from typing import Optional, cast
28import gws
29import gws.base.database.model
30import gws.base.database.util
31import gws.base.model.scalar_field
32import gws.lib.sa as sa
35@gws.ext.config.modelField('text')
36class Config(gws.base.model.scalar_field.Config):
37 """Field for text values."""
39 textSearch: Optional[gws.TextSearchOptions]
40 """Keyword search options for the field."""
43@gws.ext.props.modelField('text')
44class Props(gws.base.model.scalar_field.Props):
45 pass
48@gws.ext.object.modelField('text')
49class Object(gws.base.model.scalar_field.Object):
50 """Text field object."""
52 attributeType = gws.AttributeType.str
53 textSearch: Optional[gws.TextSearchOptions]
54 """Keyword search options, or None if the field is not searchable."""
56 def configure(self):
57 self.textSearch = self.cfg('textSearch')
58 if self.textSearch:
59 self.supportsKeywordSearch = True
61 def configure_widget(self):
62 if not super().configure_widget():
63 self.widget = self.root.create_shared(gws.ext.object.modelWidget, type='input')
64 return True
66 ##
68 def before_select(self, mc):
69 super().before_select(mc)
71 if not self.textSearch:
72 return
74 model = cast(gws.base.database.model.Object, self.model)
75 col = sa.cast(model.column(self.name), sa.String)
77 cond = gws.base.database.util.text_search_clause(col, mc.search.keyword, self.textSearch)
78 if cond is not None:
79 mc.dbSelect.keywordWhere.append(cond)