ramifice 0.4.12__py3-none-any.whl → 0.5.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.
@@ -26,7 +26,7 @@ class GeneralMixin:
26
26
  if field is None:
27
27
  continue
28
28
  if field.field_type == "TextField":
29
- field.value = data.get(lang, "") if data is not None else None
29
+ field.value = data.get(lang, "- -") if data is not None else None
30
30
  elif field.group == "pass":
31
31
  field.value = None
32
32
  else:
ramifice/commons/tools.py CHANGED
@@ -54,7 +54,7 @@ def mongo_doc_to_raw_doc(
54
54
  value = mongo_doc[f_name]
55
55
  if value is not None:
56
56
  if field_type == "TextField" and f_data.multi_language:
57
- value = value.get(lang, "") if value is not None else None
57
+ value = value.get(lang, "- -") if value is not None else None
58
58
  elif "Date" in field_type:
59
59
  if "Time" in field_type:
60
60
  value = format_datetime(
@@ -7,7 +7,7 @@ from typing import Any
7
7
 
8
8
  from pymongo.asynchronous.collection import AsyncCollection
9
9
 
10
- from ..utils import globals
10
+ from ..utils import globals, translations
11
11
  from ..utils.errors import PanicError
12
12
  from ..utils.unit import Unit
13
13
 
@@ -34,59 +34,52 @@ class UnitMixin:
34
34
  # Check the presence of a Model state.
35
35
  if model_state is None:
36
36
  raise PanicError("Error: Model State - Not found!")
37
- # Get the dynamic field type.
38
- field_type = model_state["field_name_and_type"][unit.field]
39
37
  # Get dynamic field data.
40
- choices: dict[str, float | int | str] | None = model_state["data_dynamic_fields"][
41
- unit.field
42
- ]
43
- # Check whether the type of value is valid for the type of field.
44
- if not (
45
- ("ChoiceFloat" in field_type and isinstance(unit.value, float))
46
- or ("ChoiceInt" in field_type and isinstance(unit.value, int))
47
- or ("ChoiceText" in field_type and isinstance(unit.value, str))
48
- ):
49
- msg = (
50
- "Error: Method: `unit_manager(unit: Unit)` => unit.value - "
51
- + f"The type of value `{type(unit.value)}` "
52
- + f"does not correspond to the type of field `{field_type}`!"
53
- )
54
- raise PanicError(msg)
38
+ choices: list | None = model_state["data_dynamic_fields"][unit.field]
39
+ # Get Title.
40
+ title = unit.title
41
+ title = {lang: title.get(lang, "- -") for lang in translations.LANGUAGES}
42
+ main_lang = translations.DEFAULT_LOCALE
43
+ main_title = title[main_lang]
55
44
  # Add Unit to Model State.
56
45
  if not unit.is_delete:
57
46
  if choices is not None:
58
- choices = {**choices, **{unit.title: unit.value}}
47
+ choices.append({"title": title, "value": unit.value})
59
48
  else:
60
- choices = {unit.title: unit.value}
49
+ choices = [{"title": title, "value": unit.value}]
61
50
  model_state["data_dynamic_fields"][unit.field] = choices
62
- # Delete Unit from Model State.
63
51
  else:
52
+ # Delete Unit from Model State.
64
53
  if choices is None:
65
54
  msg = (
66
55
  "Error: It is not possible to delete Unit."
67
- + f"Unit `{unit.title}: {unit.value}` not exists!"
56
+ + f"Title `{main_title}` not exists!"
68
57
  )
69
58
  raise PanicError(msg)
70
- is_key_exists: bool = unit.title in choices.keys()
59
+ is_key_exists: bool = False
60
+ for item in choices:
61
+ if main_title == item["title"][main_lang]:
62
+ is_key_exists = True
63
+ break
71
64
  if not is_key_exists:
72
65
  msg = (
73
66
  "Error: It is not possible to delete Unit."
74
- + f"Unit `{unit.title}: {unit.value}` not exists!"
67
+ + f"Title `{main_title}` not exists!"
75
68
  )
76
69
  raise PanicError(msg)
77
- del choices[unit.title]
70
+ choices = [item for item in choices if item["title"][main_lang] != main_title]
78
71
  model_state["data_dynamic_fields"][unit.field] = choices or None
79
- # Update the state of the Model in the super collection.
72
+ # Update state of current Model in super collection.
80
73
  await super_collection.replace_one(
81
74
  filter={"collection_name": model_state["collection_name"]},
82
75
  replacement=model_state,
83
76
  )
84
- # Update metadata of the current Model.
77
+ # Update metadata of current Model.
85
78
  cls.META["data_dynamic_fields"][unit.field] = choices or None
86
79
  # Update documents in the collection of the current Model.
87
80
  if unit.is_delete:
88
81
  unit_field: str = unit.field
89
- unit_value: float | int | str = unit.value
82
+ unit_value: float | int | str | None = unit.value
90
83
  collection: AsyncCollection = globals.MONGO_DATABASE[cls.META["collection_name"]]
91
84
  async for mongo_doc in collection.find():
92
85
  field_value = mongo_doc[unit_field]
ramifice/models/model.py CHANGED
@@ -68,6 +68,7 @@ class Model(metaclass=ABCMeta):
68
68
  """Injecting metadata from Model.META in params of fields."""
69
69
  metadata = self.__class__.META
70
70
  if bool(metadata):
71
+ lang = translations.CURRENT_LOCALE
71
72
  field_attrs = metadata["field_attrs"]
72
73
  data_dynamic_fields = metadata["data_dynamic_fields"]
73
74
  for f_name, f_type in self.__dict__.items():
@@ -75,7 +76,13 @@ class Model(metaclass=ABCMeta):
75
76
  f_type.id = field_attrs[f_name]["id"]
76
77
  f_type.name = field_attrs[f_name]["name"]
77
78
  if "Dyn" in f_type.field_type:
78
- f_type.choices = data_dynamic_fields[f_name]
79
+ dyn_data = data_dynamic_fields[f_name]
80
+ if dyn_data is not None:
81
+ f_type.choices = {
82
+ item["title"].get(lang, "- -"): item["value"] for item in dyn_data
83
+ }
84
+ else:
85
+ f_type.choices = None
79
86
 
80
87
  # Complect of methods for converting Model to JSON and back.
81
88
  # --------------------------------------------------------------------------
@@ -92,12 +92,12 @@ class TextGroupMixin:
92
92
  else (
93
93
  {lang: value for lang in translations.LANGUAGES}
94
94
  if isinstance(value, str)
95
- else {lang: value.get(lang, "") for lang in translations.LANGUAGES}
95
+ else {lang: value.get(lang, "- -") for lang in translations.LANGUAGES}
96
96
  )
97
97
  )
98
98
  if isinstance(value, dict):
99
99
  for lang in translations.LANGUAGES:
100
- mult_lang_text[lang] = value.get(lang, "")
100
+ mult_lang_text[lang] = value.get(lang, "- -")
101
101
  else:
102
102
  mult_lang_text[translations.CURRENT_LOCALE] = value
103
103
  value = mult_lang_text
@@ -19,7 +19,7 @@ def refresh_from_mongo_doc(inst_model: Any, mongo_doc: dict[str, Any]) -> None:
19
19
  for name, data in mongo_doc.items():
20
20
  field = model_dict[name]
21
21
  if field.field_type == "TextField" and field.multi_language:
22
- field.value = data.get(lang, "") if data is not None else None
22
+ field.value = data.get(lang, "- -") if data is not None else None
23
23
  elif field.group == "pass":
24
24
  field.value = None
25
25
  else:
ramifice/utils/unit.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Unit - Data management in dynamic fields."""
2
2
 
3
+ from typing import Any
4
+
3
5
  from .errors import PanicError
4
6
  from .mixins.json_converter import JsonMixin
5
7
 
@@ -17,19 +19,22 @@ class Unit(JsonMixin):
17
19
  def __init__( # noqa: D107
18
20
  self,
19
21
  field: str,
20
- title: str,
21
- value: float | int | str,
22
+ title: dict[str, str], # Example: {"en": "Title", "ru": "Заголовок"}
23
+ value: float | int | str | None = None, # None for is_delete=True
22
24
  is_delete: bool = False,
23
25
  ):
24
26
  # Check the match of types.
25
27
  if not isinstance(field, str):
26
28
  msg = "Class: `Unit` > Field: `field` => Not а `str` type!"
27
29
  raise PanicError(msg)
28
- if not isinstance(title, str):
29
- msg = "Class: `Unit` > Field: `title` => Not а `str` type!"
30
+ if not isinstance(title, dict):
31
+ msg = (
32
+ "Class: `Unit` > Field: `title` => Not а `str` type! "
33
+ + 'Example: {"en": "Title", "ru": "Заголовок"}'
34
+ )
30
35
  raise PanicError(msg)
31
- if not isinstance(value, (float, int, str)):
32
- msg = "Class: `Unit` > Field: `value` => Not а `float | int | str` type!"
36
+ if not isinstance(value, (float, int, str, type(None))):
37
+ msg = "Class: `Unit` > Field: `value` => Not а `float | int | str | None` type!"
33
38
  raise PanicError(msg)
34
39
  if not isinstance(is_delete, bool):
35
40
  msg = "Class: `Unit` > Field: `is_delete` => Not а `bool` type!"
@@ -42,10 +47,10 @@ class Unit(JsonMixin):
42
47
  self.value = value
43
48
  self.is_delete = is_delete
44
49
 
45
- self.check_empty_arguments()
50
+ self.check_value_arguments()
46
51
 
47
- def check_empty_arguments(self) -> None:
48
- """Error: If any of the arguments in the Unit is empty.
52
+ def check_value_arguments(self) -> None:
53
+ """Check if the values correspond to the arguments.
49
54
 
50
55
  Returns:
51
56
  `None` or raised exception `PanicError`.
@@ -56,6 +61,14 @@ class Unit(JsonMixin):
56
61
  field_name = "field"
57
62
  elif len(self.title) == 0:
58
63
  field_name = "title"
64
+ elif self.value is None and self.is_delete == False:
65
+ msg = (
66
+ "Method: `unit_manager` > "
67
+ + "Argument: `unit` > "
68
+ + f"Field: `{field_name}` => "
69
+ + "For `value` = None, `is_delete` should be True!"
70
+ )
71
+ raise PanicError(msg)
59
72
  elif isinstance(self.value, str) and len(self.value) == 0:
60
73
  field_name = "value"
61
74
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.4.12
3
+ Version: 0.5.0
4
4
  Summary: ORM-like API MongoDB for Python language.
5
5
  Project-URL: Homepage, https://github.com/kebasyaty/ramifice
6
6
  Project-URL: Documentation, https://kebasyaty.github.io/ramifice/
@@ -1,12 +1,12 @@
1
1
  ramifice/__init__.py,sha256=IuI20h84QWyFftykvte_HLft2iVxwpu0K592NypMwfo,759
2
2
  ramifice/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
3
  ramifice/commons/__init__.py,sha256=FTG78sTU0ay0rvmrq5fUmVjL-I-S7wgQq3BLcyqnjrQ,433
4
- ramifice/commons/general.py,sha256=Vq0IMuaZj-BqwENTDMg_DouMjV8EjzDy181Ujtw3JQs,5358
4
+ ramifice/commons/general.py,sha256=SmtJge18Yjz7cpc-KXo238rQl465WtTqzNnuRjHl8qs,5361
5
5
  ramifice/commons/indexes.py,sha256=hAcWKZ9MMgLbRtoQ6Af0b8r-PY0dbEYmMBl8z_d1DRo,3646
6
6
  ramifice/commons/many.py,sha256=jkah1kO1CXWPB0xW0dbMelCFBSirRYkX9a333EcPE_M,9202
7
7
  ramifice/commons/one.py,sha256=uZsgwg_GgA1VMZDPqhRFMmCdtvcv6xsL4DWbCOwGV3w,6730
8
- ramifice/commons/tools.py,sha256=hCnB95nwSCUufig9cSA5Kj9jvqRIJJ2GUSzfUK4FNXM,2363
9
- ramifice/commons/unit_manager.py,sha256=IkWqXu1PHHal0aGfx6zme81iXPeygxPqEWO-u_8RXoI,4356
8
+ ramifice/commons/tools.py,sha256=ectaILVYCSwNbB0VAys6nIhdsJbwuxAupNvcQfweC88,2366
9
+ ramifice/commons/unit_manager.py,sha256=o8Ux2y95nddo762hf1YDyp07QwvQyotR5iVoG5FZaZI,4001
10
10
  ramifice/fields/__init__.py,sha256=yRfX7Tvpuh27Ggcx5u9e1RRYK7Wu59EVJYxxetmuP1w,1290
11
11
  ramifice/fields/bool_field.py,sha256=WWubSwsFJZu8b3MviDd2zXnNYOQaYw8toklFNSTVFLA,2072
12
12
  ramifice/fields/choice_float_dyn_field.py,sha256=Yrd9cNKLm0mhU-P3IojwFRLSbuxdp7f2NMGJhrRWsf8,3093
@@ -45,7 +45,7 @@ ramifice/fields/general/number_group.py,sha256=AqlCY-t6JHZ2QVBe7mk5nPt6z8M4VJ_RA
45
45
  ramifice/fields/general/text_group.py,sha256=6GD2Fe6Toz6zZjAAlcy5rPVCAGh6Yn1ltdIrFg9RF18,1057
46
46
  ramifice/models/__init__.py,sha256=h_QQ5rSJNZ-7kmx7wIFd8E8RmUS94b_x4jdwMbq8zm4,15
47
47
  ramifice/models/decorator.py,sha256=U1ukWWq2voEwvKonQAzihqGYVsoyPrOQ2jDXJZ-UcMc,7251
48
- ramifice/models/model.py,sha256=ZvgIbcuSXuAkBl_FofOZXGwWMwlqKB-PwTMyXiqK-Fo,6610
48
+ ramifice/models/model.py,sha256=3426PGlJpb9ojc7gP80fd0cz5zsenvCyfgDaXAVk6FM,6963
49
49
  ramifice/models/pseudo.py,sha256=PhLQM4zXdaOtTSmNFzwN4twlUmdvA1D_-YOMJtaOIwM,6754
50
50
  ramifice/paladins/__init__.py,sha256=PIP3AXI2KBRXNcLJUF0d7ygJ7VLOAxlhb4HRKQ9MGYY,516
51
51
  ramifice/paladins/check.py,sha256=ennDiVAoCZIS3aKBK0eA-Vt8VJQnbIv90be5IFYraFg,7026
@@ -53,7 +53,7 @@ ramifice/paladins/delete.py,sha256=tw50E98D5eFZ7gHGnh_8ztUB1LeTeWWKZvIcQqlgbF8,3
53
53
  ramifice/paladins/password.py,sha256=w1XWh3bsncH1VTVjCLxyKI2waxMvltwcsPWW3V9Ib84,3027
54
54
  ramifice/paladins/refrash.py,sha256=fw-9x_NKGzreipBt_F9KF6FTsYm9hSzfq4ubi1FHYrQ,1065
55
55
  ramifice/paladins/save.py,sha256=EG0_v-imCQPax2pJIAXPoQcSL99g8abY2EeGJMvXBW4,3864
56
- ramifice/paladins/tools.py,sha256=fn1gve72oFRWDmFw9ESe5wd6bY5av5qyrrvWf0tw8Ns,2703
56
+ ramifice/paladins/tools.py,sha256=Xm1RhkV1GX5B6GbyGmJMBzFyDQcenBxcRjlUamIz5pA,2706
57
57
  ramifice/paladins/validation.py,sha256=gcEJXIEPu1g7Z54vl14YTs5rCmxOEYsgQH1usFfyy7k,1730
58
58
  ramifice/paladins/groups/__init__.py,sha256=hpqmWLsYAMvZHAbmMXluQSqLhkHOSTUAgLHyTM1LTYI,472
59
59
  ramifice/paladins/groups/bool_group.py,sha256=oJc9mw9KGrnK_Pj7uXixYYQAJphcXLr_xSQv3PMUlcU,792
@@ -65,7 +65,7 @@ ramifice/paladins/groups/img_group.py,sha256=RoD_QnW0F0DAzrGQmRi8jMZnWy2IomlFn6A
65
65
  ramifice/paladins/groups/num_group.py,sha256=6jT7nfIiVoQTlI2UdkcQOlHIDYjllFqSH7Nb87uJgzg,2274
66
66
  ramifice/paladins/groups/pass_group.py,sha256=YU5a-NwohEutoEx2N5JmGfg8uPiYiW0XJ8XYsOih6eA,1859
67
67
  ramifice/paladins/groups/slug_group.py,sha256=joBB5litljbv2h5JKEMzF71s_DKMWH6nzgThLiLZx2E,2307
68
- ramifice/paladins/groups/text_group.py,sha256=iftXyyqloQr9yJki__d0LwCEeerkcFquDHyI5rB8fio,4348
68
+ ramifice/paladins/groups/text_group.py,sha256=EiHGuiJKm-A4UrsV4DHoI7whL-LdQCIEvW6jX4YjfCo,4354
69
69
  ramifice/utils/__init__.py,sha256=xixHoOX4ja5jIUZemem1qn4k4aonv3G3Q76azQK_pkU,43
70
70
  ramifice/utils/errors.py,sha256=iuhq7fzpUmsOyeXeg2fJjta8yAuqlXLKsZVMpfUhtHE,1901
71
71
  ramifice/utils/fixtures.py,sha256=qsv9cg06lc82XaRlhI1j5vftmOQTTwOcDXCg_lnpK04,3159
@@ -73,13 +73,13 @@ ramifice/utils/globals.py,sha256=uR20um3Qg_1SG1t7WyWbpq8kQD-9Mslyr_c1yh5Hw9w,175
73
73
  ramifice/utils/migration.py,sha256=ol8ysNGBr0wuOwo00ZbbN0U8YKiiYVgyRYja0axdiHM,11059
74
74
  ramifice/utils/tools.py,sha256=sOKzwnvf6vdTNf9r6PKAdw6aB4undat2Z8tzS3M1GnQ,2733
75
75
  ramifice/utils/translations.py,sha256=GNGE0ULAA0aOY5pTxUd3MQW-nVaKvp6BeXWEcsR0s0o,4048
76
- ramifice/utils/unit.py,sha256=qJ2SpClsFcMRcwB_ZA-QlrB5T9OinCBiWx5KqQ9vH_A,2266
76
+ ramifice/utils/unit.py,sha256=cFnhXt8sO0X-wiuiSU7_YzmRkpdNFcf2qxfR8YPsuiE,2861
77
77
  ramifice/utils/mixins/__init__.py,sha256=-UxYokZSlEaqoIs0aPVGtzK2CgN88mTzyhryHEtt0Yo,181
78
78
  ramifice/utils/mixins/add_valid.py,sha256=TLOObedzXNA9eCylfAVbVCqIKE5sV-P5AdIN7avj-GA,407
79
79
  ramifice/utils/mixins/hooks.py,sha256=33jvJRhfnJeL2Hd_YFXk3M_7wjqHaByU2wRjKyboL6s,914
80
80
  ramifice/utils/mixins/indexing.py,sha256=Z0427HoaVRyNmSNN8Fx0mSICgAKV-gDdu3iR5qYUEbs,329
81
81
  ramifice/utils/mixins/json_converter.py,sha256=WhigXyDAV-FfILaZuwvRFRIk0D90Rv3dG5t-mv5fVyc,1107
82
- ramifice-0.4.12.dist-info/METADATA,sha256=u46bs5blVVIv_vh4jrW5ERLTFe7z8O_11-U-VK7UvLg,21965
83
- ramifice-0.4.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
- ramifice-0.4.12.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
- ramifice-0.4.12.dist-info/RECORD,,
82
+ ramifice-0.5.0.dist-info/METADATA,sha256=up068qtq-ezkO2-Y5M1-oiZoHgcA9OPdc-FXFGV5jls,21964
83
+ ramifice-0.5.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
+ ramifice-0.5.0.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
+ ramifice-0.5.0.dist-info/RECORD,,