rb-commons 0.5.22__py3-none-any.whl → 0.5.24__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.
- rb_commons/orm/managers.py +37 -9
- {rb_commons-0.5.22.dist-info → rb_commons-0.5.24.dist-info}/METADATA +1 -1
- {rb_commons-0.5.22.dist-info → rb_commons-0.5.24.dist-info}/RECORD +5 -5
- {rb_commons-0.5.22.dist-info → rb_commons-0.5.24.dist-info}/WHEEL +0 -0
- {rb_commons-0.5.22.dist-info → rb_commons-0.5.24.dist-info}/top_level.txt +0 -0
rb_commons/orm/managers.py
CHANGED
@@ -86,6 +86,7 @@ class BaseManager(Generic[ModelType]):
|
|
86
86
|
self._filtered: bool = False
|
87
87
|
self._limit: Optional[int] = None
|
88
88
|
self._order_by: List[Any] = []
|
89
|
+
self._joins: set[str] = set()
|
89
90
|
|
90
91
|
async def _smart_commit(self, instance: Optional[ModelType] = None) -> Optional[ModelType]:
|
91
92
|
if not self.session.in_transaction():
|
@@ -96,19 +97,28 @@ class BaseManager(Generic[ModelType]):
|
|
96
97
|
return None
|
97
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
|
+
|
99
108
|
parts = lookup.split("__")
|
100
109
|
operator = "eq"
|
101
110
|
if parts[-1] in {"eq", "ne", "gt", "lt", "gte", "lte", "in", "contains", "null"}:
|
102
111
|
operator = parts.pop()
|
103
112
|
|
104
113
|
current: Union[Type[ModelType], InstrumentedAttribute] = self.model
|
105
|
-
|
114
|
+
path_parts = []
|
106
115
|
for field in parts:
|
107
116
|
attr = getattr(current, field, None)
|
108
117
|
if attr is None:
|
109
118
|
raise ValueError(f"Invalid filter field: {'.'.join(parts)}")
|
110
119
|
if hasattr(attr, "property") and isinstance(attr.property, RelationshipProperty):
|
111
120
|
current = attr.property.mapper.class_
|
121
|
+
path_parts.append(field)
|
112
122
|
else:
|
113
123
|
current = attr
|
114
124
|
|
@@ -208,17 +218,21 @@ class BaseManager(Generic[ModelType]):
|
|
208
218
|
|
209
219
|
return self
|
210
220
|
|
211
|
-
def filter(self, *expressions: Any, **lookups: Any) -> "BaseManager
|
212
|
-
"""Add **AND** constraints (default behaviour)."""
|
213
|
-
|
221
|
+
def filter(self, *expressions: Any, **lookups: Any) -> "BaseManager":
|
214
222
|
self._filtered = True
|
215
|
-
|
216
|
-
if isinstance(expr, Q) or isinstance(expr, QJSON):
|
217
|
-
self.filters.append(self._q_to_expr(expr))
|
218
|
-
else:
|
219
|
-
self.filters.append(expr)
|
223
|
+
|
220
224
|
for k, v in lookups.items():
|
225
|
+
root = k.split("__", 1)[0]
|
226
|
+
if hasattr(self.model, root):
|
227
|
+
attr = getattr(self.model, root)
|
228
|
+
if hasattr(attr, "property") and isinstance(attr.property, RelationshipProperty):
|
229
|
+
self._joins.add(root)
|
230
|
+
|
221
231
|
self.filters.append(self._parse_lookup(k, v))
|
232
|
+
|
233
|
+
for expr in expressions:
|
234
|
+
self.filters.append(self._q_to_expr(expr) if isinstance(expr, Q) else expr)
|
235
|
+
|
222
236
|
return self
|
223
237
|
|
224
238
|
def or_filter(self, *expressions: Any, **lookups: Any) -> "BaseManager[ModelType]":
|
@@ -273,9 +287,23 @@ class BaseManager(Generic[ModelType]):
|
|
273
287
|
self.filters.clear()
|
274
288
|
self._filtered = False
|
275
289
|
self._limit = None
|
290
|
+
self._joins.clear()
|
276
291
|
|
277
292
|
async def all(self, load_all_relations: bool = False):
|
278
293
|
stmt = select(self.model)
|
294
|
+
|
295
|
+
for rel_path in self._joins:
|
296
|
+
rel_model = self.model
|
297
|
+
join_attr = None
|
298
|
+
|
299
|
+
for part in rel_path.split("__"):
|
300
|
+
join_attr = getattr(rel_model, part)
|
301
|
+
if not hasattr(join_attr, "property"):
|
302
|
+
raise ValueError(f"Invalid join path: {rel_path}")
|
303
|
+
rel_model = join_attr.property.mapper.class_
|
304
|
+
|
305
|
+
stmt = stmt.join(join_attr)
|
306
|
+
|
279
307
|
if self.filters:
|
280
308
|
stmt = stmt.filter(and_(*self.filters))
|
281
309
|
if self._order_by:
|
@@ -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=
|
16
|
+
rb_commons/orm/managers.py,sha256=wFYZx6RxsB58p2_nJStS8BLiiW4pGYF-zgQ3X9R8esM,19767
|
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.
|
26
|
-
rb_commons-0.5.
|
27
|
-
rb_commons-0.5.
|
28
|
-
rb_commons-0.5.
|
25
|
+
rb_commons-0.5.24.dist-info/METADATA,sha256=SXvgYuSQpp5vNxAunOl9g76z8OHHDwKwPpzxYyJDNcY,6571
|
26
|
+
rb_commons-0.5.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
27
|
+
rb_commons-0.5.24.dist-info/top_level.txt,sha256=HPx_WAYo3_fbg1WCeGHsz3wPGio1ucbnrlm2lmqlJog,11
|
28
|
+
rb_commons-0.5.24.dist-info/RECORD,,
|
File without changes
|
File without changes
|