GeneralManager 0.12.1__py3-none-any.whl → 0.12.2__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.
- general_manager/interface/databaseBasedInterface.py +46 -9
- general_manager/interface/databaseInterface.py +12 -8
- general_manager/interface/models.py +1 -1
- {generalmanager-0.12.1.dist-info → generalmanager-0.12.2.dist-info}/METADATA +1 -1
- {generalmanager-0.12.1.dist-info → generalmanager-0.12.2.dist-info}/RECORD +8 -8
- {generalmanager-0.12.1.dist-info → generalmanager-0.12.2.dist-info}/WHEEL +0 -0
- {generalmanager-0.12.1.dist-info → generalmanager-0.12.2.dist-info}/licenses/LICENSE +0 -0
- {generalmanager-0.12.1.dist-info → generalmanager-0.12.2.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,7 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from typing import Type, Any, Callable, TYPE_CHECKING, TypeVar, Generic, cast
|
3
3
|
from django.db import models
|
4
|
+
|
4
5
|
from datetime import datetime, timedelta
|
5
6
|
from general_manager.measurement.measurement import Measurement
|
6
7
|
from general_manager.measurement.measurementField import MeasurementField
|
@@ -66,6 +67,25 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
66
67
|
instance = self.getHistoricalRecord(instance, search_date)
|
67
68
|
return instance
|
68
69
|
|
70
|
+
@staticmethod
|
71
|
+
def __parseKwargs(**kwargs: Any) -> dict[str, Any]:
|
72
|
+
"""
|
73
|
+
Parses keyword arguments to ensure they are compatible with the model's fields.
|
74
|
+
|
75
|
+
Converts GeneralManager instances to their primary key values and returns a dictionary of parsed arguments.
|
76
|
+
"""
|
77
|
+
from general_manager.manager.generalManager import GeneralManager
|
78
|
+
|
79
|
+
parsed_kwargs: dict[str, Any] = {}
|
80
|
+
for key, value in kwargs.items():
|
81
|
+
if isinstance(value, GeneralManager):
|
82
|
+
parsed_kwargs[key] = getattr(
|
83
|
+
value._interface, "_instance", value.identification["id"]
|
84
|
+
)
|
85
|
+
else:
|
86
|
+
parsed_kwargs[key] = value
|
87
|
+
return parsed_kwargs
|
88
|
+
|
69
89
|
@classmethod
|
70
90
|
def filter(cls, **kwargs: Any) -> DatabaseBucket:
|
71
91
|
"""
|
@@ -77,6 +97,9 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
77
97
|
Returns:
|
78
98
|
A DatabaseBucket wrapping the filtered queryset and associated metadata.
|
79
99
|
"""
|
100
|
+
|
101
|
+
kwargs = cls.__parseKwargs(**kwargs)
|
102
|
+
|
80
103
|
return DatabaseBucket(
|
81
104
|
cls._model.objects.filter(**kwargs),
|
82
105
|
cls._parent_class,
|
@@ -94,6 +117,8 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
94
117
|
Returns:
|
95
118
|
A DatabaseBucket wrapping the queryset of excluded model instances.
|
96
119
|
"""
|
120
|
+
kwargs = cls.__parseKwargs(**kwargs)
|
121
|
+
|
97
122
|
return DatabaseBucket(
|
98
123
|
cls._model.objects.exclude(**kwargs),
|
99
124
|
cls._parent_class,
|
@@ -135,9 +160,9 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
135
160
|
@classmethod
|
136
161
|
def getAttributeTypes(cls) -> dict[str, AttributeTypedDict]:
|
137
162
|
"""
|
138
|
-
Return a dictionary mapping each attribute name
|
163
|
+
Return a dictionary mapping each model attribute name to its type information and metadata.
|
139
164
|
|
140
|
-
|
165
|
+
Includes standard fields, custom fields, foreign keys, many-to-many, and reverse relation fields, excluding GenericForeignKey fields. For each attribute, provides its Python type (translated from Django field types when possible), required and editable status, whether it is derived, and its default value. For related models with a general manager class, the type is set to that class.
|
141
166
|
|
142
167
|
Returns:
|
143
168
|
dict[str, AttributeTypedDict]: Mapping of attribute names to their type information and metadata.
|
@@ -178,7 +203,8 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
178
203
|
fields[field_name] = {
|
179
204
|
"type": type(field),
|
180
205
|
"is_derived": False,
|
181
|
-
"is_required": not field.null
|
206
|
+
"is_required": not field.null
|
207
|
+
and field.default is models.NOT_PROVIDED,
|
182
208
|
"is_editable": field.editable,
|
183
209
|
"default": field.default,
|
184
210
|
}
|
@@ -196,7 +222,7 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
196
222
|
):
|
197
223
|
related_model = related_model._general_manager_class # type: ignore
|
198
224
|
|
199
|
-
|
225
|
+
if related_model is not None:
|
200
226
|
default = None
|
201
227
|
if hasattr(field, "default"):
|
202
228
|
default = field.default # type: ignore
|
@@ -247,12 +273,12 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
247
273
|
@classmethod
|
248
274
|
def getAttributes(cls) -> dict[str, Callable[[DBBasedInterface], Any]]:
|
249
275
|
"""
|
250
|
-
Return a
|
276
|
+
Return a mapping of attribute names to callables that extract values from a DBBasedInterface instance.
|
251
277
|
|
252
|
-
The
|
278
|
+
The returned dictionary includes accessors for custom fields, standard model fields, foreign keys, many-to-many relations, and reverse relations. For related models with a general manager class, the accessor returns an instance or queryset of that class; otherwise, it returns the related object or queryset directly. Raises a ValueError if a field name conflict is detected.
|
253
279
|
|
254
280
|
Returns:
|
255
|
-
dict
|
281
|
+
dict[str, Callable[[DBBasedInterface], Any]]: Mapping of attribute names to callables for retrieving values from a DBBasedInterface instance.
|
256
282
|
"""
|
257
283
|
from general_manager.manager.generalManager import GeneralManager
|
258
284
|
|
@@ -306,12 +332,22 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
306
332
|
cls._model._meta.get_field(field_name).related_model,
|
307
333
|
"_general_manager_class",
|
308
334
|
):
|
335
|
+
related_model = cast(
|
336
|
+
Type[models.Model],
|
337
|
+
cls._model._meta.get_field(field_name).related_model,
|
338
|
+
)
|
339
|
+
related_fields = [
|
340
|
+
f
|
341
|
+
for f in related_model._meta.get_fields()
|
342
|
+
if f.related_model == cls._model
|
343
|
+
]
|
344
|
+
|
309
345
|
field_values[
|
310
346
|
f"{field_name}_list"
|
311
|
-
] = lambda self, field_name=field_name: self._instance._meta.get_field(
|
347
|
+
] = lambda self, field_name=field_name, related_fields=related_fields: self._instance._meta.get_field(
|
312
348
|
field_name
|
313
349
|
).related_model._general_manager_class.filter(
|
314
|
-
**{
|
350
|
+
**{related_field.name: self.pk for related_field in related_fields}
|
315
351
|
)
|
316
352
|
else:
|
317
353
|
field_values[f"{field_name}_list"] = (
|
@@ -319,6 +355,7 @@ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
|
|
319
355
|
self._instance, field_call
|
320
356
|
).all()
|
321
357
|
)
|
358
|
+
|
322
359
|
return field_values
|
323
360
|
|
324
361
|
@staticmethod
|
@@ -84,19 +84,23 @@ class DatabaseInterface(DBBasedInterface[GeneralManagerModel]):
|
|
84
84
|
instance: GeneralManagerModel, many_to_many_kwargs: dict[str, list[Any]]
|
85
85
|
) -> GeneralManagerModel:
|
86
86
|
"""
|
87
|
-
|
87
|
+
Set many-to-many relationship fields on a model instance using provided values.
|
88
88
|
|
89
|
-
|
90
|
-
instance: The model instance to update.
|
91
|
-
many_to_many_kwargs: A dictionary containing many-to-many field names and their corresponding values.
|
92
|
-
|
93
|
-
Returns:
|
94
|
-
The updated model instance.
|
89
|
+
Converts lists of `GeneralManager` instances to their corresponding IDs before updating the relationships. Returns the updated instance.
|
95
90
|
"""
|
91
|
+
from general_manager.manager.generalManager import GeneralManager
|
92
|
+
|
96
93
|
for key, value in many_to_many_kwargs.items():
|
97
94
|
if not value:
|
98
95
|
continue
|
99
|
-
field_name = key.
|
96
|
+
field_name = key.removesuffix("_id_list")
|
97
|
+
if isinstance(value, list) and all(
|
98
|
+
isinstance(v, GeneralManager) for v in value
|
99
|
+
):
|
100
|
+
value = [
|
101
|
+
v.identification["id"] if hasattr(v, "identification") else v
|
102
|
+
for v in value
|
103
|
+
]
|
100
104
|
getattr(instance, field_name).set(value)
|
101
105
|
|
102
106
|
return instance
|
@@ -39,7 +39,7 @@ def getFullCleanMethode(model: Type[models.Model]) -> Callable[..., None]:
|
|
39
39
|
except ValidationError as e:
|
40
40
|
errors.update(e.message_dict)
|
41
41
|
|
42
|
-
rules: list[Rule] = getattr(self._meta, "rules")
|
42
|
+
rules: list[Rule] = getattr(self._meta, "rules", [])
|
43
43
|
for rule in rules:
|
44
44
|
if rule.evaluate(self) is False:
|
45
45
|
error_message = rule.getErrorMessage()
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: GeneralManager
|
3
|
-
Version: 0.12.
|
3
|
+
Version: 0.12.2
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
6
6
|
License-Expression: MIT
|
@@ -19,9 +19,9 @@ general_manager/factory/factoryMethods.py,sha256=9Bag891j0XHe3dUBAFi7gUKcKeUwcBZ
|
|
19
19
|
general_manager/interface/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
20
|
general_manager/interface/baseInterface.py,sha256=cFsDU-nhj_O6Gir3eO0ukGKNn9Pplhe6gEMccHNi4O0,8648
|
21
21
|
general_manager/interface/calculationInterface.py,sha256=fTD3WQpsn3ImaxGW5S-JwVJyJJPoPp2mR6lAambdB8U,4755
|
22
|
-
general_manager/interface/databaseBasedInterface.py,sha256=
|
23
|
-
general_manager/interface/databaseInterface.py,sha256=
|
24
|
-
general_manager/interface/models.py,sha256=
|
22
|
+
general_manager/interface/databaseBasedInterface.py,sha256=uB4_kJ1kNSK-QnUrFKR0zrDP-UulBKeeHIslXqEdU4Q,23058
|
23
|
+
general_manager/interface/databaseInterface.py,sha256=WRJehbV2Rov9rSL001eEdzacCYzx2AzvOCkwZ2Zv8ow,7001
|
24
|
+
general_manager/interface/models.py,sha256=iYuSTMWKGrH5cjmxTii8HRpSmUUMhtw6xvatRzB4zuA,3315
|
25
25
|
general_manager/interface/readOnlyInterface.py,sha256=TkfbOeaa2wCq5kCv0a3IwJWcYOTVbtNsdNWmGAz0Mns,11217
|
26
26
|
general_manager/manager/__init__.py,sha256=l3RYp62aEhj3Y975_XUTIzo35LUnkTJHkb_hgChnXXI,111
|
27
27
|
general_manager/manager/generalManager.py,sha256=4Qn9TYpZpqh5qC95BEAQhpiZgDrRXrAJjO2BbbXUdNg,9129
|
@@ -51,8 +51,8 @@ general_manager/utils/makeCacheKey.py,sha256=UlFsxHXgsYy69AAelkF6GDvY4h7AImT2bBn
|
|
51
51
|
general_manager/utils/noneToZero.py,sha256=KfQtMQnrT6vsYST0K7lv6pVujkDcK3XL8czHYOhgqKQ,539
|
52
52
|
general_manager/utils/pathMapping.py,sha256=nrz5owQg2a69Yig1eCXorR9U0NSw7NmBAk5OkeoHTdA,6842
|
53
53
|
general_manager/utils/testing.py,sha256=ElZ8p4iZHxsHjDN8Lm5TmI6527CW747ltDOmtY6gAhk,11872
|
54
|
-
generalmanager-0.12.
|
55
|
-
generalmanager-0.12.
|
56
|
-
generalmanager-0.12.
|
57
|
-
generalmanager-0.12.
|
58
|
-
generalmanager-0.12.
|
54
|
+
generalmanager-0.12.2.dist-info/licenses/LICENSE,sha256=YGFm0ieb4KpkMRRt2qnWue6uFh0cUMtobwEBkHwajhc,1450
|
55
|
+
generalmanager-0.12.2.dist-info/METADATA,sha256=5pw28Ng1rz1k2PTf7bI-EbulRwyZHkdikpqYAxRqJ24,6206
|
56
|
+
generalmanager-0.12.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
57
|
+
generalmanager-0.12.2.dist-info/top_level.txt,sha256=sTDtExP9ga-YP3h3h42yivUY-A2Q23C2nw6LNKOho4I,16
|
58
|
+
generalmanager-0.12.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|