ramifice 0.4.1__py3-none-any.whl → 0.4.3__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.
@@ -99,6 +99,8 @@ class CheckMixin(
99
99
  err_msg = error_map.get(field_name)
100
100
  if bool(err_msg):
101
101
  field_data.errors.append(err_msg)
102
+ if not params["is_error_symptom"]:
103
+ params["is_error_symptom"] = True
102
104
  # Checking the fields by groups.
103
105
  if not field_data.ignored:
104
106
  group = field_data.group
@@ -20,6 +20,7 @@ class NumGroupMixin:
20
20
  async def num_group(self, params: dict[str, Any]) -> None:
21
21
  """Checking number fields."""
22
22
  field = params["field_data"]
23
+ field_name = field.name
23
24
  # Get current value.
24
25
  value = field.value
25
26
  if value is None:
@@ -37,7 +38,7 @@ class NumGroupMixin:
37
38
  err_msg = translations._("Required field !")
38
39
  accumulate_error(err_msg, params)
39
40
  if params["is_save"]:
40
- params["result_map"][field.name] = None
41
+ params["result_map"][field_name] = None
41
42
  return
42
43
  # Validation the `max_number` field attribute.
43
44
  max_number = field.max_number
@@ -54,9 +55,9 @@ class NumGroupMixin:
54
55
  )
55
56
  accumulate_error(err_msg, params)
56
57
  # Validation the `unique` field attribute.
57
- if field.unique and not await check_uniqueness(value, params):
58
+ if field.unique and not await check_uniqueness(value, params, field_name):
58
59
  err_msg = translations._("Is not unique !")
59
60
  accumulate_error(err_msg, params)
60
61
  # Insert result.
61
62
  if params["is_save"]:
62
- params["result_map"][field.name] = value
63
+ params["result_map"][field_name] = value
@@ -25,23 +25,24 @@ class SlugGroupMixin:
25
25
  return
26
26
  #
27
27
  field = params["field_data"]
28
+ field_name = field.name
28
29
  raw_str_list: list[str] = []
29
30
  slug_sources = field.slug_sources
30
31
  #
31
- for field_name, field_data in self.__dict__.items():
32
+ for _field_name, field_data in self.__dict__.items():
32
33
  if callable(field_data):
33
34
  continue
34
- if field_name in slug_sources:
35
+ if _field_name in slug_sources:
35
36
  value = field_data.value
36
37
  if value is None:
37
38
  value = field_data.__dict__.get("default")
38
39
  if value is not None:
39
- raw_str_list.append(value if field_name != "_id" else str(value))
40
+ raw_str_list.append(value if _field_name != "_id" else str(value))
40
41
  else:
41
42
  err_msg = (
42
43
  f"Model: `{params['full_model_name']}` > "
43
- + f"Field: `{field.name}` => "
44
- + f"{field_name} - "
44
+ + f"Field: `{field_name}` => "
45
+ + f"{_field_name} - "
45
46
  + "This field is specified in slug_sources. "
46
47
  + "This field should be mandatory or assign a default value."
47
48
  )
@@ -51,13 +52,17 @@ class SlugGroupMixin:
51
52
  # Convert to slug.
52
53
  value = slugify("-".join(raw_str_list))
53
54
  # Validation of uniqueness of the value.
54
- if not await check_uniqueness(value, params):
55
+ if not await check_uniqueness(
56
+ value,
57
+ params,
58
+ field_name,
59
+ ):
55
60
  err_msg = (
56
61
  f"Model: `{params['full_model_name']}` > "
57
- + f"Field: `{field.name}` > "
62
+ + f"Field: `{field_name}` > "
58
63
  + f"Parameter: `slug_sources` => "
59
64
  + "At least one field should be unique!"
60
65
  )
61
66
  raise PanicError(err_msg)
62
67
  # Add value to map.
63
- params["result_map"][field.name] = value
68
+ params["result_map"][field_name] = value
@@ -25,6 +25,7 @@ class TextGroupMixin:
25
25
  async def text_group(self, params: dict[str, Any]) -> None:
26
26
  """Checking text fields."""
27
27
  field = params["field_data"]
28
+ field_name = field.name
28
29
  field_type: str = field.field_type
29
30
  is_text_field: bool = "TextField" == field_type
30
31
  # Get current value.
@@ -42,7 +43,7 @@ class TextGroupMixin:
42
43
  err_msg = translations._("Required field !")
43
44
  accumulate_error(err_msg, params)
44
45
  if params["is_save"]:
45
- params["result_map"][field.name] = None
46
+ params["result_map"][field_name] = None
46
47
  return
47
48
  # Validation the `maxlength` field attribute.
48
49
  maxlength: int | None = field.__dict__.get("maxlength")
@@ -50,7 +51,12 @@ class TextGroupMixin:
50
51
  err_msg = translations._("The length of the string exceeds maxlength=%d !" % maxlength)
51
52
  accumulate_error(err_msg, params)
52
53
  # Validation the `unique` field attribute.
53
- if field.unique and not await check_uniqueness(value, params):
54
+ if field.unique and not await check_uniqueness(
55
+ value,
56
+ params,
57
+ field_name,
58
+ is_text_field,
59
+ ):
54
60
  err_msg = translations._("Is not unique !")
55
61
  accumulate_error(err_msg, params)
56
62
  # Validation Email, Url, IP, Color, Phone.
@@ -81,7 +87,7 @@ class TextGroupMixin:
81
87
  if params["is_save"]:
82
88
  if is_text_field:
83
89
  mult_lang_text: dict[str, str] = (
84
- params["curr_doc"][field.name] if params["is_update"] else {}
90
+ params["curr_doc"][field_name] if params["is_update"] else {}
85
91
  )
86
92
  if isinstance(value, dict):
87
93
  for lang, text in value.items():
@@ -89,4 +95,4 @@ class TextGroupMixin:
89
95
  else:
90
96
  mult_lang_text[translations.CURRENT_LOCALE] = value
91
97
  value = mult_lang_text
92
- params["result_map"][field.name] = value
98
+ params["result_map"][field_name] = value
@@ -54,14 +54,26 @@ def accumulate_error(err_msg: str, params: dict[str, Any]) -> None:
54
54
  async def check_uniqueness(
55
55
  value: str | int | float,
56
56
  params: dict[str, Any],
57
+ field_name: str | None = None,
58
+ is_text_field: bool = False,
57
59
  ) -> bool:
58
60
  """Check the uniqueness of the value in the collection."""
59
61
  if not params["is_migrate_model"]:
60
62
  return True
61
- q_filter = {
62
- "$and": [
63
- {"_id": {"$ne": params["doc_id"]}},
64
- {params["field_data"].name: value},
65
- ],
66
- }
63
+ q_filter = None
64
+ if is_text_field:
65
+ lang_filter = [{f"{field_name}.{lang}": value} for lang in translations.LANGUAGES]
66
+ q_filter = {
67
+ "$and": [
68
+ {"_id": {"$ne": params["doc_id"]}},
69
+ {"$or": lang_filter},
70
+ ],
71
+ }
72
+ else:
73
+ q_filter = {
74
+ "$and": [
75
+ {"_id": {"$ne": params["doc_id"]}},
76
+ {field_name: value},
77
+ ],
78
+ }
67
79
  return await params["collection"].find_one(q_filter) is None
@@ -68,7 +68,7 @@ async def apply_fixture(
68
68
  print(colored("\nFIXTURE:", "red", attrs=["bold"]))
69
69
  print(colored(fixture_path, "blue", attrs=["bold"]))
70
70
  inst_model.print_err()
71
- raise PanicError("!!!")
71
+ raise PanicError("Error: Fixtures")
72
72
  # Get data for document.
73
73
  checked_data: dict[str, Any] = result_check["data"]
74
74
  # Add date and time.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.4.1
3
+ Version: 0.4.3
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/
@@ -135,12 +135,22 @@ from datetime import datetime
135
135
 
136
136
  from pymongo import AsyncMongoClient
137
137
  from ramifice import model, translations, migration
138
- from ramifice.fields import DateField, EmailField, ImageField, PasswordField, TextField, FileField
138
+ from ramifice.fields import (
139
+ DateField,
140
+ EmailField,
141
+ FileField,
142
+ ImageField,
143
+ PasswordField,
144
+ TextField,
145
+ )
139
146
 
140
147
 
141
148
  @model(service_name="Accounts")
142
149
  class User:
150
+ """Model of User."""
151
+
143
152
  def fields(self):
153
+ """For adding fields."""
144
154
  # For custom translations.
145
155
  gettext = translations.gettext
146
156
  ngettext = translations.ngettext
@@ -48,12 +48,12 @@ ramifice/models/decorator.py,sha256=jOEn-0v0m_tM7mow45-tM-8LADUmwlG2DWZsEuC9S_w,
48
48
  ramifice/models/model.py,sha256=ZvgIbcuSXuAkBl_FofOZXGwWMwlqKB-PwTMyXiqK-Fo,6610
49
49
  ramifice/models/pseudo.py,sha256=PhLQM4zXdaOtTSmNFzwN4twlUmdvA1D_-YOMJtaOIwM,6754
50
50
  ramifice/paladins/__init__.py,sha256=PIP3AXI2KBRXNcLJUF0d7ygJ7VLOAxlhb4HRKQ9MGYY,516
51
- ramifice/paladins/check.py,sha256=SdDC9cE4I_Pt9L9NTatEzNYtwpcCIy03yCJqi1O6qM8,6796
51
+ ramifice/paladins/check.py,sha256=9VQmr3GXaGitMQl-3KOZP-2_xYC7JG_jDLM62iKx1b4,6903
52
52
  ramifice/paladins/delete.py,sha256=tw50E98D5eFZ7gHGnh_8ztUB1LeTeWWKZvIcQqlgbF8,3352
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=d3sKH6GzPlt7SxR9JyTEY3YgmqhwNvwPOg3hg80-zoU,2297
56
+ ramifice/paladins/tools.py,sha256=SCmESo8isvcy0yk43Rj1J5BZ1xSZbNV1KLhhBrzfezY,2687
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
@@ -62,13 +62,13 @@ ramifice/paladins/groups/date_group.py,sha256=B9usKKrHX16F1ckik60Xkub1tawgNENSHT
62
62
  ramifice/paladins/groups/file_group.py,sha256=-xgtrLOTlKXc71Mnbu3I_LbYnTEd8OprnhtYcJbaDtg,2932
63
63
  ramifice/paladins/groups/id_group.py,sha256=q5BeoM1e7mZmX0zVgemva9K-9ihJKBrX8kxvMh-uhhQ,1268
64
64
  ramifice/paladins/groups/img_group.py,sha256=RoD_QnW0F0DAzrGQmRi8jMZnWy2IomlFn6A5jTM02iA,5542
65
- ramifice/paladins/groups/num_group.py,sha256=FHT9D2S3TsxdMypqoBgZsIzlaLY0KjXdPYqB95vvTRI,2229
65
+ ramifice/paladins/groups/num_group.py,sha256=6jT7nfIiVoQTlI2UdkcQOlHIDYjllFqSH7Nb87uJgzg,2274
66
66
  ramifice/paladins/groups/pass_group.py,sha256=YU5a-NwohEutoEx2N5JmGfg8uPiYiW0XJ8XYsOih6eA,1859
67
- ramifice/paladins/groups/slug_group.py,sha256=o-lr1ssfhTcBovlS6pWA2TQdg1qI6tlDjZ2iKkz-584,2191
68
- ramifice/paladins/groups/text_group.py,sha256=HZTocj8Y8tbVDkvKm8jSQQSGhsotPJWtOcb4zEpt6OY,3881
67
+ ramifice/paladins/groups/slug_group.py,sha256=joBB5litljbv2h5JKEMzF71s_DKMWH6nzgThLiLZx2E,2307
68
+ ramifice/paladins/groups/text_group.py,sha256=67gk-vEoZImifCqIzWYexc0Yj2__srFAUqmOHRhBgOk,4005
69
69
  ramifice/utils/__init__.py,sha256=xixHoOX4ja5jIUZemem1qn4k4aonv3G3Q76azQK_pkU,43
70
70
  ramifice/utils/errors.py,sha256=iuhq7fzpUmsOyeXeg2fJjta8yAuqlXLKsZVMpfUhtHE,1901
71
- ramifice/utils/fixtures.py,sha256=NtxOnZslYJb4yvRpZbs3ckugmTwHQFS_9iCt2zddOC0,3102
71
+ ramifice/utils/fixtures.py,sha256=Krl31nNShEg6A15Q8WRDqIai0bPyaJuK8jEGt5ySzao,3114
72
72
  ramifice/utils/globals.py,sha256=uR20um3Qg_1SG1t7WyWbpq8kQD-9Mslyr_c1yh5Hw9w,1751
73
73
  ramifice/utils/migration.py,sha256=LON53a8oBpjc9ox-FzqBEGsAWnqW8t-CWBkRC7BbwxI,11022
74
74
  ramifice/utils/tools.py,sha256=sOKzwnvf6vdTNf9r6PKAdw6aB4undat2Z8tzS3M1GnQ,2733
@@ -79,7 +79,7 @@ ramifice/utils/mixins/add_valid.py,sha256=TLOObedzXNA9eCylfAVbVCqIKE5sV-P5AdIN7a
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.1.dist-info/METADATA,sha256=AYPSoWwW4UiCfShGcS4HDvmfkVhHbru6B2dsYCZZXy0,20961
83
- ramifice-0.4.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
- ramifice-0.4.1.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
- ramifice-0.4.1.dist-info/RECORD,,
82
+ ramifice-0.4.3.dist-info/METADATA,sha256=JSgLC_LmwUU-SwrQp7uEF5lQDn9xsAAUe_F08XHY1d0,21049
83
+ ramifice-0.4.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
+ ramifice-0.4.3.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
+ ramifice-0.4.3.dist-info/RECORD,,