GeneralManager 0.7.0__py3-none-any.whl → 0.9.0__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.
@@ -1,12 +1,5 @@
1
1
  from __future__ import annotations
2
- from typing import (
3
- Type,
4
- ClassVar,
5
- Any,
6
- Callable,
7
- TYPE_CHECKING,
8
- TypeVar,
9
- )
2
+ from typing import Type, ClassVar, Any, Callable, TYPE_CHECKING, TypeVar, Generic
10
3
  from django.db import models
11
4
  from django.conf import settings
12
5
  from datetime import datetime, timedelta
@@ -30,6 +23,11 @@ from general_manager.interface.baseInterface import (
30
23
  )
31
24
  from general_manager.manager.input import Input
32
25
  from general_manager.bucket.databaseBucket import DatabaseBucket
26
+ from general_manager.interface.models import (
27
+ GeneralManagerBasisModel,
28
+ GeneralManagerModel,
29
+ getFullCleanMethode,
30
+ )
33
31
 
34
32
  if TYPE_CHECKING:
35
33
  from general_manager.manager.generalManager import GeneralManager
@@ -39,69 +37,11 @@ if TYPE_CHECKING:
39
37
  modelsModel = TypeVar("modelsModel", bound=models.Model)
40
38
 
41
39
 
42
- def getFullCleanMethode(model: Type[models.Model]) -> Callable[..., None]:
43
- """
44
- Generates a custom `full_clean` method for a Django model that combines standard validation with additional rule-based checks.
45
-
46
- The returned method first performs Django's built-in model validation, then evaluates any custom rules defined in the model's `_meta.rules` attribute. If any validation or rule fails, a `ValidationError` is raised containing all collected errors.
47
- """
48
-
49
- def full_clean(self: models.Model, *args: Any, **kwargs: Any):
50
- errors: dict[str, Any] = {}
51
- try:
52
- super(model, self).full_clean(*args, **kwargs) # type: ignore
53
- except ValidationError as e:
54
- errors.update(e.message_dict)
55
-
56
- rules: list[Rule] = getattr(self._meta, "rules")
57
- for rule in rules:
58
- if not rule.evaluate(self):
59
- error_message = rule.getErrorMessage()
60
- if error_message:
61
- errors.update(error_message)
62
-
63
- if errors:
64
- raise ValidationError(errors)
65
-
66
- return full_clean
40
+ MODEL_TYPE = TypeVar("MODEL_TYPE", bound=GeneralManagerBasisModel)
67
41
 
68
42
 
69
- class GeneralManagerBasisModel(models.Model):
70
- _general_manager_class: ClassVar[Type[GeneralManager]]
71
- is_active = models.BooleanField(default=True)
72
- history = HistoricalRecords(inherit=True)
73
-
74
- class Meta:
75
- abstract = True
76
-
77
-
78
- class GeneralManagerModel(GeneralManagerBasisModel):
79
- changed_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
80
- changed_by_id: int
81
-
82
- @property
83
- def _history_user(self) -> AbstractUser:
84
- """
85
- Returns the user who last modified this model instance.
86
- """
87
- return self.changed_by
88
-
89
- @_history_user.setter
90
- def _history_user(self, value: AbstractUser) -> None:
91
- """
92
- Sets the user responsible for the latest change to the model instance.
93
-
94
- Args:
95
- value: The user to associate with the change.
96
- """
97
- self.changed_by = value
98
-
99
- class Meta: # type: ignore
100
- abstract = True
101
-
102
-
103
- class DBBasedInterface(InterfaceBase):
104
- _model: Type[GeneralManagerBasisModel]
43
+ class DBBasedInterface(InterfaceBase, Generic[MODEL_TYPE]):
44
+ _model: Type[MODEL_TYPE]
105
45
  input_fields: dict[str, Input] = {"id": Input(int)}
106
46
 
107
47
  def __init__(
@@ -111,9 +51,9 @@ class DBBasedInterface(InterfaceBase):
111
51
  **kwargs: dict[str, Any],
112
52
  ):
113
53
  """
114
- Initializes the interface instance and loads the corresponding model record.
115
-
116
- If a `search_date` is provided, retrieves the historical record as of that date; otherwise, loads the current record.
54
+ Initialize the interface and load the associated model instance.
55
+
56
+ If `search_date` is provided, loads the historical record as of that date; otherwise, loads the current record.
117
57
  """
118
58
  super().__init__(*args, **kwargs)
119
59
  self.pk = self.identification["id"]
@@ -200,9 +140,12 @@ class DBBasedInterface(InterfaceBase):
200
140
  @classmethod
201
141
  def getAttributeTypes(cls) -> dict[str, AttributeTypedDict]:
202
142
  """
203
- Returns a dictionary mapping attribute names to their type information and metadata.
204
-
205
- The returned dictionary includes all model fields, custom fields, foreign keys, many-to-many, and reverse relation fields. Each entry provides the Python type (translated from Django field types when possible), whether the field is required, editable, and its default value. For related models that have a general manager class, the type is set to that class.
143
+ Return a dictionary mapping attribute names to metadata describing their types and properties.
144
+
145
+ The dictionary includes all model fields, custom fields, foreign keys, many-to-many, and reverse relation fields. For each attribute, the metadata specifies its Python type (translated from Django field types when possible), whether it is required, editable, derived, and its default value. For related models with a general manager class, the type is set to that class.
146
+
147
+ Returns:
148
+ dict[str, AttributeTypedDict]: Mapping of attribute names to their type information and metadata.
206
149
  """
207
150
  TRANSLATION: dict[Type[models.Field[Any, Any]], type] = {
208
151
  models.fields.BigAutoField: int,
@@ -228,6 +171,7 @@ class DBBasedInterface(InterfaceBase):
228
171
  field: models.Field = getattr(cls._model, field_name)
229
172
  fields[field_name] = {
230
173
  "type": type(field),
174
+ "is_derived": False,
231
175
  "is_required": not field.null,
232
176
  "is_editable": field.editable,
233
177
  "default": field.default,
@@ -238,6 +182,7 @@ class DBBasedInterface(InterfaceBase):
238
182
  field: models.Field = getattr(cls._model, field_name).field
239
183
  fields[field_name] = {
240
184
  "type": type(field),
185
+ "is_derived": False,
241
186
  "is_required": not field.null,
242
187
  "is_editable": field.editable,
243
188
  "default": field.default,
@@ -255,6 +200,7 @@ class DBBasedInterface(InterfaceBase):
255
200
  elif related_model is not None:
256
201
  fields[field_name] = {
257
202
  "type": related_model,
203
+ "is_derived": False,
258
204
  "is_required": not field.null,
259
205
  "is_editable": field.editable,
260
206
  "default": field.default,
@@ -280,6 +226,7 @@ class DBBasedInterface(InterfaceBase):
280
226
  fields[f"{field_name}_list"] = {
281
227
  "type": related_model,
282
228
  "is_required": False,
229
+ "is_derived": not bool(field.many_to_many),
283
230
  "is_editable": bool(field.many_to_many and field.editable),
284
231
  "default": None,
285
232
  }
@@ -453,9 +400,9 @@ class DBBasedInterface(InterfaceBase):
453
400
  ) -> tuple[attributes, interfaceBaseClass, relatedClass]:
454
401
  # Felder aus der Interface-Klasse sammeln
455
402
  """
456
- Dynamically creates a Django model class, its associated interface class, and a factory class based on the provided interface definition.
403
+ Dynamically generates a Django model class, its associated interface class, and a factory class from an interface definition.
457
404
 
458
- This method extracts fields and meta information from the interface class, constructs a new Django model inheriting from the specified base model class, attaches custom validation rules if present, and generates corresponding interface and factory classes. The resulting classes are returned for integration into the general manager framework.
405
+ This method collects fields and metadata from the provided interface class, creates a new Django model inheriting from the specified base model class, attaches custom validation rules if present, and constructs corresponding interface and factory classes. The updated attributes dictionary, the new interface class, and the newly created model class are returned for integration into the general manager framework.
459
406
 
460
407
  Parameters:
461
408
  name: The name for the dynamically created model class.
@@ -464,7 +411,7 @@ class DBBasedInterface(InterfaceBase):
464
411
  base_model_class: The base class to use for the new model (defaults to GeneralManagerModel).
465
412
 
466
413
  Returns:
467
- A tuple containing the updated attributes dictionary, the new interface class, and the newly created model class.
414
+ tuple: A tuple containing the updated attributes dictionary, the new interface class, and the newly created model class.
468
415
  """
469
416
  model_fields: dict[str, Any] = {}
470
417
  meta_class = None
@@ -11,14 +11,25 @@ from general_manager.interface.databaseBasedInterface import (
11
11
  )
12
12
 
13
13
 
14
- class DatabaseInterface(DBBasedInterface):
14
+ class DatabaseInterface(DBBasedInterface[GeneralManagerModel]):
15
15
  _interface_type = "database"
16
16
 
17
17
  @classmethod
18
18
  def create(
19
- cls, creator_id: int, history_comment: str | None = None, **kwargs: Any
19
+ cls, creator_id: int | None, history_comment: str | None = None, **kwargs: Any
20
20
  ) -> int:
21
+ """
22
+ Create a new model instance with the provided attributes and optional history tracking.
23
+
24
+ Validates input attributes, separates and sets many-to-many relationships, saves the instance with optional creator and history comment, and returns the primary key of the created instance.
25
+
26
+ Parameters:
27
+ creator_id (int | None): The ID of the user creating the instance, or None if not applicable.
28
+ history_comment (str | None): Optional comment to record in the instance's history.
21
29
 
30
+ Returns:
31
+ int: The primary key of the newly created instance.
32
+ """
22
33
  cls._checkForInvalidKwargs(cls._model, kwargs=kwargs)
23
34
  kwargs, many_to_many_kwargs = cls._sortKwargs(cls._model, kwargs)
24
35
  instance = cls.__setAttrForWrite(cls._model(), kwargs)
@@ -27,9 +38,18 @@ class DatabaseInterface(DBBasedInterface):
27
38
  return pk
28
39
 
29
40
  def update(
30
- self, creator_id: int, history_comment: str | None = None, **kwargs: Any
41
+ self, creator_id: int | None, history_comment: str | None = None, **kwargs: Any
31
42
  ) -> int:
43
+ """
44
+ Update the current model instance with new attribute values and many-to-many relationships, saving changes with optional history tracking.
45
+
46
+ Parameters:
47
+ creator_id (int | None): The ID of the user making the update, or None if not specified.
48
+ history_comment (str | None): An optional comment describing the reason for the update.
32
49
 
50
+ Returns:
51
+ int: The primary key of the updated instance.
52
+ """
33
53
  self._checkForInvalidKwargs(self._model, kwargs=kwargs)
34
54
  kwargs, many_to_many_kwargs = self._sortKwargs(self._model, kwargs)
35
55
  instance = self.__setAttrForWrite(self._model.objects.get(pk=self.pk), kwargs)
@@ -37,7 +57,19 @@ class DatabaseInterface(DBBasedInterface):
37
57
  self.__setManyToManyAttributes(instance, many_to_many_kwargs)
38
58
  return pk
39
59
 
40
- def deactivate(self, creator_id: int, history_comment: str | None = None) -> int:
60
+ def deactivate(
61
+ self, creator_id: int | None, history_comment: str | None = None
62
+ ) -> int:
63
+ """
64
+ Deactivate the current model instance by setting its `is_active` flag to `False` and recording the change with an optional history comment.
65
+
66
+ Parameters:
67
+ creator_id (int | None): The ID of the user performing the deactivation, or None if not specified.
68
+ history_comment (str | None): An optional comment to include in the instance's history log.
69
+
70
+ Returns:
71
+ int: The primary key of the deactivated instance.
72
+ """
41
73
  instance = self._model.objects.get(pk=self.pk)
42
74
  instance.is_active = False
43
75
  if history_comment:
@@ -79,7 +111,12 @@ class DatabaseInterface(DBBasedInterface):
79
111
  if isinstance(value, GeneralManager):
80
112
  value = value.identification["id"]
81
113
  key = f"{key}_id"
82
- setattr(instance, key, value)
114
+ try:
115
+ setattr(instance, key, value)
116
+ except ValueError as e:
117
+ raise ValueError(f"Invalid value for {key}: {value}") from e
118
+ except TypeError as e:
119
+ raise TypeError(f"Type error for {key}: {e}") from e
83
120
  return instance
84
121
 
85
122
  @staticmethod
@@ -89,7 +126,7 @@ class DatabaseInterface(DBBasedInterface):
89
126
  for key in kwargs:
90
127
  temp_key = key.split("_id_list")[0] # Remove '_id_list' suffix
91
128
  if temp_key not in attributes and temp_key not in field_names:
92
- raise ValueError(f"{key} does not exsist in {model.__name__}")
129
+ raise ValueError(f"{key} does not exist in {model.__name__}")
93
130
 
94
131
  @staticmethod
95
132
  def _sortKwargs(
@@ -106,17 +143,15 @@ class DatabaseInterface(DBBasedInterface):
106
143
  @classmethod
107
144
  @transaction.atomic
108
145
  def _save_with_history(
109
- cls, instance: GeneralManagerModel, creator_id: int, history_comment: str | None
146
+ cls,
147
+ instance: GeneralManagerModel,
148
+ creator_id: int | None,
149
+ history_comment: str | None,
110
150
  ) -> int:
111
151
  """
112
- Saves a model instance with validation and optional history tracking.
152
+ Atomically saves a model instance with validation and optional history comment.
113
153
 
114
- Sets the `changed_by_id` field, validates the instance, applies a history comment if provided, and saves the instance within an atomic transaction.
115
-
116
- Args:
117
- instance: The model instance to save.
118
- creator_id: The ID of the user making the change.
119
- history_comment: Optional comment describing the reason for the change.
154
+ Sets the `changed_by_id` field, validates the instance, applies a history comment if provided, and saves the instance within a database transaction.
120
155
 
121
156
  Returns:
122
157
  The primary key of the saved instance.
@@ -0,0 +1,88 @@
1
+ from __future__ import annotations
2
+ from typing import Type, ClassVar, Any, Callable, TYPE_CHECKING, TypeVar
3
+ from django.db import models
4
+ from django.conf import settings
5
+ from simple_history.models import HistoricalRecords # type: ignore
6
+ from django.core.exceptions import ValidationError
7
+
8
+
9
+ if TYPE_CHECKING:
10
+ from general_manager.manager.generalManager import GeneralManager
11
+ from django.contrib.auth.models import AbstractUser
12
+ from general_manager.rule.rule import Rule
13
+
14
+ modelsModel = TypeVar("modelsModel", bound=models.Model)
15
+
16
+
17
+ def getFullCleanMethode(model: Type[models.Model]) -> Callable[..., None]:
18
+ """
19
+ Return a custom `full_clean` method for a Django model that performs both standard validation and additional rule-based checks.
20
+
21
+ The generated method first applies Django's built-in model validation, then evaluates custom rules defined in the model's `_meta.rules` attribute. If any validation or rule fails, it raises a `ValidationError` containing all collected errors.
22
+
23
+ Parameters:
24
+ model (Type[models.Model]): The Django model class for which to generate the custom `full_clean` method.
25
+
26
+ Returns:
27
+ Callable[..., None]: A `full_clean` method that can be assigned to the model class.
28
+ """
29
+
30
+ def full_clean(self: models.Model, *args: Any, **kwargs: Any):
31
+ """
32
+ Performs full validation on the model instance, including both standard Django validation and custom rule-based checks.
33
+
34
+ Aggregates errors from Django's built-in validation and any additional rules defined in the model's `_meta.rules` attribute. Raises a `ValidationError` containing all collected errors if any validation or rule check fails.
35
+ """
36
+ errors: dict[str, Any] = {}
37
+ try:
38
+ super(model, self).full_clean(*args, **kwargs) # type: ignore
39
+ except ValidationError as e:
40
+ errors.update(e.message_dict)
41
+
42
+ rules: list[Rule] = getattr(self._meta, "rules")
43
+ for rule in rules:
44
+ if not rule.evaluate(self):
45
+ error_message = rule.getErrorMessage()
46
+ if error_message:
47
+ errors.update(error_message)
48
+
49
+ if errors:
50
+ raise ValidationError(errors)
51
+
52
+ return full_clean
53
+
54
+
55
+ class GeneralManagerBasisModel(models.Model):
56
+ _general_manager_class: ClassVar[Type[GeneralManager]]
57
+ is_active = models.BooleanField(default=True)
58
+ history = HistoricalRecords(inherit=True)
59
+
60
+ class Meta:
61
+ abstract = True
62
+
63
+
64
+ class GeneralManagerModel(GeneralManagerBasisModel):
65
+ changed_by = models.ForeignKey(
66
+ settings.AUTH_USER_MODEL, on_delete=models.PROTECT, null=True, blank=True
67
+ )
68
+ changed_by_id: int | None
69
+
70
+ @property
71
+ def _history_user(self) -> AbstractUser | None:
72
+ """
73
+ Returns the user who last modified this model instance, or None if no user is set.
74
+ """
75
+ return self.changed_by
76
+
77
+ @_history_user.setter
78
+ def _history_user(self, value: AbstractUser) -> None:
79
+ """
80
+ Set the user responsible for the most recent change to the model instance.
81
+
82
+ Parameters:
83
+ value (AbstractUser): The user to associate with the latest modification.
84
+ """
85
+ self.changed_by = value
86
+
87
+ class Meta: # type: ignore
88
+ abstract = True
@@ -24,17 +24,16 @@ if TYPE_CHECKING:
24
24
  logger = logging.getLogger(__name__)
25
25
 
26
26
 
27
- class ReadOnlyInterface(DBBasedInterface):
27
+ class ReadOnlyInterface(DBBasedInterface[GeneralManagerBasisModel]):
28
28
  _interface_type = "readonly"
29
- _model: Type[GeneralManagerBasisModel]
30
29
  _parent_class: Type[GeneralManager]
31
30
 
32
31
  @staticmethod
33
32
  def getUniqueFields(model: Type[models.Model]) -> set[str]:
34
33
  """
35
- Return the set of field names that uniquely identify instances of the given Django model.
34
+ Return a set of field names that uniquely identify instances of the specified Django model.
36
35
 
37
- Considers fields marked as unique (excluding "id"), unique_together constraints, and UniqueConstraint definitions.
36
+ Considers fields marked as unique (excluding "id"), as well as fields defined in `unique_together` and `UniqueConstraint` constraints.
38
37
  """
39
38
  opts = model._meta
40
39
  unique_fields: set[str] = set()
@@ -57,9 +56,9 @@ class ReadOnlyInterface(DBBasedInterface):
57
56
  @classmethod
58
57
  def syncData(cls) -> None:
59
58
  """
60
- Synchronizes the associated Django model with the JSON data from the parent class, ensuring records match exactly.
59
+ Synchronizes the associated Django model with JSON data from the parent class, ensuring the database records match the provided data exactly.
61
60
 
62
- Parses the JSON data, creates or updates model instances based on unique fields, and marks as inactive any database records not present in the JSON data. Raises a ValueError if required attributes are missing, if the JSON data is invalid, or if no unique fields are defined.
61
+ Parses the JSON data, creates or updates model instances based on unique fields, and deactivates any database records not present in the JSON data. Raises a ValueError if required attributes are missing, if the JSON data is invalid, or if no unique fields are defined.
63
62
  """
64
63
  if cls.ensureSchemaIsUpToDate(cls._parent_class, cls._model):
65
64
  logger.warning(
@@ -138,22 +137,18 @@ class ReadOnlyInterface(DBBasedInterface):
138
137
  new_manager_class: Type[GeneralManager], model: Type[models.Model]
139
138
  ) -> list[Warning]:
140
139
  """
141
- Checks whether the database schema for the given model matches the model definition.
142
-
143
- Parameters:
144
- new_manager_class (Type[GeneralManager]): The manager class associated with the model.
145
- model (Type[models.Model]): The Django model to check.
140
+ Check if the database schema for a Django model matches its model definition.
146
141
 
147
142
  Returns:
148
- list[Warning]: A list of Django Warning objects describing schema issues, or an empty list if the schema is up to date.
143
+ A list of Django Warning objects describing schema issues, such as missing tables or column mismatches. Returns an empty list if the schema is up to date.
149
144
  """
150
145
 
151
146
  def table_exists(table_name: str) -> bool:
152
147
  """
153
- Check if a database table with the given name exists.
148
+ Determine whether a database table with the specified name exists.
154
149
 
155
150
  Parameters:
156
- table_name (str): The name of the database table to check.
151
+ table_name (str): Name of the database table to check.
157
152
 
158
153
  Returns:
159
154
  bool: True if the table exists, False otherwise.
@@ -166,11 +161,12 @@ class ReadOnlyInterface(DBBasedInterface):
166
161
  model: Type[models.Model], table: str
167
162
  ) -> tuple[list[str], list[str]]:
168
163
  """
169
- Compare a Django model's fields to the columns of a database table.
164
+ Compares the fields of a Django model to the columns of a specified database table.
170
165
 
171
166
  Returns:
172
- missing (list[str]): Columns defined in the model but missing from the database table.
173
- extra (list[str]): Columns present in the database table but not defined in the model.
167
+ A tuple containing two lists:
168
+ - The first list contains column names defined in the model but missing from the database table.
169
+ - The second list contains column names present in the database table but not defined in the model.
174
170
  """
175
171
  with connection.cursor() as cursor:
176
172
  desc = connection.introspection.get_table_description(cursor, table)
@@ -208,7 +204,7 @@ class ReadOnlyInterface(DBBasedInterface):
208
204
  """
209
205
  Decorator for post-creation hooks that registers a new manager class as read-only.
210
206
 
211
- After executing the wrapped post-creation function, this decorator appends the newly created manager class to the `read_only_classes` list in the meta-class, marking it as a read-only interface.
207
+ After the wrapped post-creation function is executed, the newly created manager class is added to the meta-class's list of read-only classes, marking it as a read-only interface.
212
208
  """
213
209
 
214
210
  def wrapper(
@@ -217,12 +213,9 @@ class ReadOnlyInterface(DBBasedInterface):
217
213
  model: Type[GeneralManagerBasisModel],
218
214
  ):
219
215
  """
220
- Registers the newly created class as a read-only class after invoking the wrapped post-creation function.
216
+ Registers a newly created manager class as read-only after executing the wrapped post-creation function.
221
217
 
222
- Parameters:
223
- new_class (Type[GeneralManager]): The newly created manager class to register.
224
- interface_cls (Type[ReadOnlyInterface]): The associated read-only interface class.
225
- model (Type[GeneralManagerModel]): The model class associated with the manager.
218
+ This function appends the new manager class to the list of read-only classes in the meta system, ensuring it is recognized as a read-only interface.
226
219
  """
227
220
  from general_manager.manager.meta import GeneralManagerMeta
228
221
 
@@ -234,16 +227,28 @@ class ReadOnlyInterface(DBBasedInterface):
234
227
  @staticmethod
235
228
  def readOnlyPreCreate(func: Callable[..., Any]) -> Callable[..., Any]:
236
229
  """
237
- Decorator for pre-creation hook functions to ensure the base model class is set to ReadOnlyModel.
230
+ Decorator for pre-creation hook functions that ensures the base model class is set to `GeneralManagerBasisModel`.
238
231
 
239
- Wraps a pre-creation function, injecting ReadOnlyModel as the base model class argument before the GeneralManager instance is created.
232
+ Wraps a pre-creation function, injecting `GeneralManagerBasisModel` as the `base_model_class` argument before the manager class is created.
240
233
  """
234
+
241
235
  def wrapper(
242
236
  name: generalManagerClassName,
243
237
  attrs: attributes,
244
238
  interface: interfaceBaseClass,
245
239
  base_model_class=GeneralManagerBasisModel,
246
240
  ):
241
+ """
242
+ Wraps a function to ensure the `base_model_class` argument is set to `GeneralManagerBasisModel` before invocation.
243
+
244
+ Parameters:
245
+ name: The name of the manager class being created.
246
+ attrs: Attributes for the manager class.
247
+ interface: The interface base class to use.
248
+
249
+ Returns:
250
+ The result of calling the wrapped function with `base_model_class` set to `GeneralManagerBasisModel`.
251
+ """
247
252
  return func(
248
253
  name, attrs, interface, base_model_class=GeneralManagerBasisModel
249
254
  )
@@ -253,12 +258,14 @@ class ReadOnlyInterface(DBBasedInterface):
253
258
  @classmethod
254
259
  def handleInterface(cls) -> tuple[classPreCreationMethod, classPostCreationMethod]:
255
260
  """
256
- Return the pre- and post-creation hook methods for integrating this interface with a GeneralManager.
261
+ Return the pre- and post-creation hook methods for integrating the interface with a manager meta-class system.
257
262
 
258
- The returned tuple contains the pre-creation method, which injects the base model class, and the post-creation method, which registers the class as read-only. These hooks are intended for use by GeneralManagerMeta during the manager class lifecycle.
263
+ The returned tuple includes:
264
+ - A pre-creation method that ensures the base model class is set for read-only operation.
265
+ - A post-creation method that registers the manager class as read-only.
259
266
 
260
267
  Returns:
261
- tuple: A pair of methods for pre- and post-creation processing.
268
+ tuple: The pre-creation and post-creation hook methods for manager class lifecycle integration.
262
269
  """
263
270
  return cls.readOnlyPreCreate(cls._preCreate), cls.readOnlyPostCreate(
264
271
  cls._postCreate