77 get_args ,
88 get_origin ,
99) # noqa: UP035
10+ from unicodedata import normalize
1011
1112from beanie import Document , PydanticObjectId
1213from beanie .odm .utils .encoder import Encoder
2122from pydantic .aliases import PydanticUndefined
2223from pydantic .fields import FieldInfo
2324
25+ from tekst .config import get_config
2426from tekst .types import (
2527 ExcludeFromModelVariants ,
2628 SchemaOptionalNonNullable ,
@@ -85,14 +87,21 @@ class NoAliasEncoder(Encoder):
8587 """
8688
8789 def _iter_model_items (self , obj : BaseModel ) -> Iterable [tuple [str , Any ]]:
88- exclude , keep_nulls = self .exclude , self .keep_nulls
8990 for key , value in obj .__iter__ ():
90- if key not in exclude and (value is not None or keep_nulls ):
91+ if key not in self . exclude and (value is not None or self . keep_nulls ):
9192 # this is where we use "key" directly, without considering aliases
9293 yield key , value
9394
9495
9596_no_alias_encoder = NoAliasEncoder (to_db = True , keep_nulls = False ).encode
97+ _unicode_nf = get_config ().db .unicode_nf
98+
99+
100+ def _apply_unicode_nf (str_v ):
101+ if _unicode_nf is not None :
102+ return normalize (_unicode_nf , str_v )
103+ else : # pragma: no cover
104+ return str_v
96105
97106
98107class DocumentBase (Document ):
@@ -104,8 +113,8 @@ class Settings:
104113 validate_on_save = True
105114 keep_nulls = False
106115 bson_encoders = {
107- # see docstring of NoAliasEncoder for rationale!
108- BaseModel : _no_alias_encoder ,
116+ BaseModel : _no_alias_encoder , # see docstring of NoAliasEncoder
117+ str : _apply_unicode_nf ,
109118 }
110119
111120 def __init__ (self , * args , ** kwargs ):
0 commit comments