rb-commons 0.5.25__py3-none-any.whl → 0.5.26__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -96,53 +96,55 @@ class BaseManager(Generic[ModelType]):
96
96
  return instance
97
97
  return None
98
98
 
99
- def _parse_lookup(self, lookup: str, value: Any):
100
- root = lookup.split("__", 1)[0]
101
-
102
- if hasattr(self.model, root):
103
- attr0 = getattr(self.model, root)
104
- if hasattr(attr0, "property") and isinstance(attr0.property, RelationshipProperty):
105
- self._joins.add(root)
106
- parts = lookup.split("__")
107
-
108
- parts = lookup.split("__")
109
- operator = "eq"
110
- if parts[-1] in {"eq", "ne", "gt", "lt", "gte", "lte", "in", "contains", "null"}:
111
- operator = parts.pop()
112
-
113
- current: Union[Type[ModelType], InstrumentedAttribute] = self.model
114
- path_parts = []
115
- for field in parts:
116
- attr = getattr(current, field, None)
117
- if attr is None:
118
- raise ValueError(f"Invalid filter field: {'.'.join(parts)}")
119
- if hasattr(attr, "property") and isinstance(attr.property, RelationshipProperty):
120
- current = attr.property.mapper.class_
121
- path_parts.append(field)
122
- else:
123
- current = attr
124
-
99
+ def _build_comparison(self, col, operator: str, value: Any):
125
100
  if operator == "eq":
126
- return current == value
101
+ return col == value
127
102
  if operator == "ne":
128
- return current != value
103
+ return col != value
129
104
  if operator == "gt":
130
- return current > value
105
+ return col > value
131
106
  if operator == "lt":
132
- return current < value
107
+ return col < value
133
108
  if operator == "gte":
134
- return current >= value
109
+ return col >= value
135
110
  if operator == "lte":
136
- return current <= value
111
+ return col <= value
137
112
  if operator == "in":
138
- if not isinstance(value, (list, tuple, set)):
139
- raise ValueError(f"{lookup}__in requires an iterable")
140
- return current.in_(value)
113
+ return col.in_(value)
141
114
  if operator == "contains":
142
- return current.ilike(f"%{value}%")
115
+ return col.ilike(f"%{value}%")
143
116
  if operator == "null":
144
- return current.is_(None) if value else current.isnot(None)
145
- raise ValueError(f"Unsupported operator in lookup: {lookup}")
117
+ return col.is_(None) if value else col.isnot(None)
118
+ raise ValueError(f"Unsupported operator: {operator}")
119
+
120
+ def _parse_lookup(self, lookup: str, value: Any):
121
+ parts = lookup.split("__")
122
+ operator = "eq"
123
+ if parts[-1] in {"eq", "ne", "gt", "lt", "gte", "lte", "in", "contains", "null"}:
124
+ operator = parts.pop()
125
+
126
+ current_model = self.model
127
+ attr = None
128
+ relationship_attr = None
129
+ for idx, part in enumerate(parts):
130
+ candidate = getattr(current_model, part, None)
131
+ if candidate is None:
132
+ raise ValueError(f"Invalid filter field: {lookup!r}")
133
+
134
+ prop = getattr(candidate, "property", None)
135
+ if prop and isinstance(prop, RelationshipProperty):
136
+ relationship_attr = candidate
137
+ current_model = prop.mapper.class_
138
+ else:
139
+ attr = candidate
140
+
141
+ if relationship_attr:
142
+ col = attr
143
+ expr = self._build_comparison(col, operator, value)
144
+ return relationship_attr.any(expr)
145
+
146
+ col = getattr(self.model, parts[0], None) if len(parts) == 1 else attr
147
+ return self._build_comparison(col, operator, value)
146
148
 
147
149
  def _q_to_expr(self, q: Union[Q, QJSON]):
148
150
  if isinstance(q, QJSON):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rb-commons
3
- Version: 0.5.25
3
+ Version: 0.5.26
4
4
  Summary: Commons of project and simplified orm based on sqlalchemy.
5
5
  Home-page: https://github.com/RoboSell-organization/rb-commons
6
6
  Author: Abdulvoris
@@ -13,7 +13,7 @@ rb_commons/http/consul.py,sha256=Ioq72VD1jGwoC96set7n2SgxN40olzI-myA2lwKkYi4,186
13
13
  rb_commons/http/exceptions.py,sha256=EGRMr1cRgiJ9Q2tkfANbf0c6-zzXf1CD6J3cmCaT_FA,1885
14
14
  rb_commons/orm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
15
  rb_commons/orm/exceptions.py,sha256=1aMctiEwrPjyehoXVX1l6ML5ZOhmDkmBISzlTD5ey1Y,509
16
- rb_commons/orm/managers.py,sha256=vELttfVNHoBOeFLV5XmBh4cS_1PAYAPfyCLbBDkzjc0,19827
16
+ rb_commons/orm/managers.py,sha256=le1mQVEr9gIEkd56nCyiEYZNcESqErv6Jsxf1PGhPvA,19761
17
17
  rb_commons/orm/services.py,sha256=71eRcJ4TxZvzNz-hLXo12X4U7PGK54ZfbLAb27AjZi8,1589
18
18
  rb_commons/permissions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  rb_commons/permissions/role_permissions.py,sha256=4dV89z6ggzLqCCiFYlMp7kQVJRESu6MHpkT5ZNjLo6A,1096
@@ -22,7 +22,7 @@ rb_commons/schemes/jwt.py,sha256=ZKLJ5D3fcEmEKySjzbxEgUcza4K-oPoHr14_Z0r9Yic,249
22
22
  rb_commons/schemes/pagination.py,sha256=8VZW1wZGJIPR9jEBUgppZUoB4uqP8ORudHkMwvEJSxg,1866
23
23
  rb_commons/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  rb_commons/utils/media.py,sha256=J2Zi0J28DhcVQVzt-myNNVuzj9Msaetul53VjZtdDdc,820
25
- rb_commons-0.5.25.dist-info/METADATA,sha256=DQmBk2r4PKfLLFtGYRYuUF266dCEu86o-KR5bQHkYqE,6571
26
- rb_commons-0.5.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
- rb_commons-0.5.25.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
- rb_commons-0.5.25.dist-info/RECORD,,
25
+ rb_commons-0.5.26.dist-info/METADATA,sha256=ZfmInMrRweoC6XQhn1Q8YQ9chd4fkyMLZ8t7_lyIPCA,6571
26
+ rb_commons-0.5.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
27
+ rb_commons-0.5.26.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
28
+ rb_commons-0.5.26.dist-info/RECORD,,