@@ -292,20 +292,18 @@ def query_params(self) -> Dict[str, Union[str, bytes]]:
292
292
293
293
@property
294
294
def score_field_name (self ) -> str :
295
- return self .score_field .field .alias
295
+ return self .score_field .field .name
296
296
297
297
@property
298
298
def vector_field_name (self ) -> str :
299
- return self .vector_field .field .alias
299
+ return self .vector_field .field .name
300
300
301
301
302
302
ExpressionOrNegated = Union [Expression , NegatedExpression ]
303
303
304
304
305
305
class ExpressionProxy :
306
- def __init__ (
307
- self , field : PydanticFieldInfo , parents : List [Tuple [str , "RedisModel" ]]
308
- ):
306
+ def __init__ (self , field : "FieldInfo" , parents : List [Tuple [str , "RedisModel" ]]):
309
307
self .field = field
310
308
self .parents = parents .copy () # Ensure a copy is stored
311
309
@@ -389,7 +387,7 @@ def __getattr__(self, item):
389
387
if isinstance (attr , self .__class__ ):
390
388
# Clone the parents to ensure isolation
391
389
new_parents = self .parents .copy ()
392
- new_parent = (self .field .alias , outer_type )
390
+ new_parent = (self .field .name , outer_type )
393
391
if new_parent not in new_parents :
394
392
new_parents .append (new_parent )
395
393
attr .parents = new_parents
@@ -524,17 +522,18 @@ def validate_sort_fields(self, sort_fields: List[str]):
524
522
)
525
523
field_proxy : ExpressionProxy = getattr (self .model , field_name )
526
524
527
- if not getattr (field_proxy .field , "sortable" , False ):
525
+ if (
526
+ not field_proxy .field .sortable is True
527
+ and not field_proxy .field .index is True
528
+ ):
528
529
raise QueryNotSupportedError (
529
530
f"You tried sort by { field_name } , but { self .model } does "
530
- f"not define that field as sortable. Docs: { ERRORS_URL } #E2"
531
+ f"not define that field as sortable or indexed . Docs: { ERRORS_URL } #E2"
531
532
)
532
533
return sort_fields
533
534
534
535
@staticmethod
535
- def resolve_field_type (
536
- field : PydanticFieldInfo , op : Operators
537
- ) -> RediSearchFieldTypes :
536
+ def resolve_field_type (field : "FieldInfo" , op : Operators ) -> RediSearchFieldTypes :
538
537
field_info : Union [FieldInfo , PydanticFieldInfo ] = field
539
538
540
539
if getattr (field_info , "primary_key" , None ) is True :
@@ -543,7 +542,7 @@ def resolve_field_type(
543
542
fts = getattr (field_info , "full_text_search" , None )
544
543
if fts is not True : # Could be PydanticUndefined
545
544
raise QuerySyntaxError (
546
- f"You tried to do a full-text search on the field '{ field .alias } ', "
545
+ f"You tried to do a full-text search on the field '{ field .name } ', "
547
546
f"but the field is not indexed for full-text search. Use the "
548
547
f"full_text_search=True option. Docs: { ERRORS_URL } #E3"
549
548
)
@@ -793,7 +792,7 @@ def resolve_redisearch_query(cls, expression: ExpressionOrNegated) -> str:
793
792
result += f"({ cls .resolve_redisearch_query (expression .left )} )"
794
793
elif isinstance (expression .left , FieldInfo ):
795
794
field_type = cls .resolve_field_type (expression .left , expression .op )
796
- field_name = expression .left .alias
795
+ field_name = expression .left .name
797
796
field_info = expression .left
798
797
if not field_info or not getattr (field_info , "index" , None ):
799
798
raise QueryNotSupportedError (
@@ -1059,6 +1058,8 @@ def __dataclass_transform__(
1059
1058
1060
1059
1061
1060
class FieldInfo (PydanticFieldInfo ):
1061
+ name : str
1062
+
1062
1063
def __init__ (self , default : Any = Undefined , ** kwargs : Any ) -> None :
1063
1064
primary_key = kwargs .pop ("primary_key" , False )
1064
1065
sortable = kwargs .pop ("sortable" , Undefined )
@@ -1297,20 +1298,22 @@ def __new__(cls, name, bases, attrs, **kwargs): # noqa C901
1297
1298
# Create proxies for each model field so that we can use the field
1298
1299
# in queries, like Model.get(Model.field_name == 1)
1299
1300
# Only set if the model is has index=True
1300
- if kwargs .get ("index" , None ) == True :
1301
- new_class .model_config ["index" ] = True
1302
- for field_name , field in new_class .model_fields .items ():
1301
+ is_indexed = kwargs .get ("index" , None ) is True
1302
+ new_class .model_config ["index" ] = is_indexed
1303
+
1304
+ for field_name , field in new_class .model_fields .items ():
1305
+ if field .__class__ is PydanticFieldInfo :
1306
+ field = FieldInfo (** field ._attributes_set )
1307
+ setattr (new_class , field_name , field )
1308
+
1309
+ if is_indexed :
1303
1310
setattr (new_class , field_name , ExpressionProxy (field , []))
1304
1311
1305
- # We need to set alias equal the field name here to allow downstream processes to have access to it.
1306
- # Processes like the query builder use it.
1307
- if not field .alias :
1308
- field .alias = field_name
1312
+ # we need to set the field name for use in queries
1313
+ field .name = field_name
1309
1314
1310
- if getattr (field , "primary_key" , None ) is True :
1311
- new_class ._meta .primary_key = PrimaryKey (
1312
- name = field_name , field = field
1313
- )
1315
+ if field .primary_key is True :
1316
+ new_class ._meta .primary_key = PrimaryKey (name = field_name , field = field )
1314
1317
1315
1318
if not getattr (new_class ._meta , "global_key_prefix" , None ):
1316
1319
new_class ._meta .global_key_prefix = getattr (
0 commit comments