diff --git a/backend/models/base_doc.py b/backend/models/base_doc.py index 77fca47..bd6722d 100644 --- a/backend/models/base_doc.py +++ b/backend/models/base_doc.py @@ -15,10 +15,18 @@ class QueryExpression: def __init__(self, field_name: str): self.field_name = field_name + def __getattr__(self, name: str) -> 'QueryExpression': + """Handle nested field access like FLID.identity""" + return QueryExpression(f"{self.field_name}.{name}") + def __eq__(self, other: Any) -> Dict[str, Any]: """Handle field == value comparisons""" return {self.field_name: other} + def __deepcopy__(self, memo): + """Support deepcopy for Pydantic field processing""" + return QueryExpression(self.field_name) + def __ne__(self, other: Any) -> Dict[str, Any]: """Handle field != value comparisons""" return {self.field_name: {"$ne": other}} @@ -61,6 +69,10 @@ class FieldDescriptor: raise TypeError(f"Field {self.field_name} must be {self.field_type}") instance.__dict__[self.field_name] = value + def __deepcopy__(self, memo): + """Support deepcopy for Pydantic field processing""" + return FieldDescriptor(self.field_name, self.field_type) + class FieldCondition: """Represents a field condition for MongoDB queries""" @@ -84,18 +96,9 @@ _tenant_db_context: contextvars.ContextVar[Optional[AsyncIOMotorDatabase]] = con class QueryModelMeta(ModelMetaclass): """Metaclass: automatically create FieldDescriptor for model fields""" def __new__(cls, name: str, bases: tuple, namespace: dict): - # Get model field annotations (like name: str -> "name" and str) - annotations = namespace.get("__annotations__", {}) - # Create the class first using Pydantic's metaclass + # Don't add FieldDescriptor during __new__ to avoid interfering with Pydantic's processing new_class = super().__new__(cls, name, bases, namespace) - - # After Pydantic processes the fields, add the descriptors as class attributes - for field_name, field_type in annotations.items(): - if field_name != 'id': # Skip the id field as it's handled specially - # Add the descriptor as a class attribute - setattr(new_class, field_name, FieldDescriptor(field_name, field_type)) - return new_class def __getattr__(cls, name: str):