ramifice 0.5.0__py3-none-any.whl → 0.5.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.
ramifice/models/model.py CHANGED
@@ -82,6 +82,8 @@ class Model(metaclass=ABCMeta):
82
82
  item["title"].get(lang, "- -"): item["value"] for item in dyn_data
83
83
  }
84
84
  else:
85
+ # This is necessary for
86
+ # `paladins > refrash > RefrashMixin > refrash_from_db`.
85
87
  f_type.choices = None
86
88
 
87
89
  # Complect of methods for converting Model to JSON and back.
@@ -171,7 +173,7 @@ class Model(metaclass=ABCMeta):
171
173
  json_dict = json.loads(json_str)
172
174
  return cls.from_dict_only_value(json_dict)
173
175
 
174
- def refrash_fields(self, only_value_dict: dict[str, Any]) -> None:
176
+ def refrash_fields_only_value(self, only_value_dict: dict[str, Any]) -> None:
175
177
  """Partial or complete update a `value` of fields."""
176
178
  for name, data in self.__dict__.items():
177
179
  if callable(data):
ramifice/models/pseudo.py CHANGED
@@ -166,7 +166,7 @@ class PseudoModel(metaclass=ABCMeta):
166
166
  json_dict = json.loads(json_str)
167
167
  return cls.from_dict_only_value(json_dict)
168
168
 
169
- def refrash_fields(self, only_value_dict: dict[str, Any]) -> None:
169
+ def refrash_fields_only_value(self, only_value_dict: dict[str, Any]) -> None:
170
170
  """Partial or complete update a `value` of fields."""
171
171
  for name, data in self.__dict__.items():
172
172
  if callable(data):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ramifice
3
- Version: 0.5.0
3
+ Version: 0.5.2
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/
@@ -129,35 +129,42 @@ uv add ramifice
129
129
  It is recommended to look at examples [here](https://github.com/kebasyaty/ramifice/tree/v0/examples "here").
130
130
 
131
131
  ```python
132
+ import re
132
133
  import asyncio
133
- import pprint
134
134
  from datetime import datetime
135
+ import pprint
135
136
 
136
137
  from pymongo import AsyncMongoClient
137
138
  from ramifice import model, translations, migration
138
139
  from ramifice.fields import (
139
140
  BooleanField,
140
141
  DateField,
142
+ DateTimeField,
141
143
  EmailField,
142
- FileField,
143
144
  ImageField,
144
145
  PasswordField,
146
+ PhoneField,
147
+ SlugField,
145
148
  TextField,
146
149
  )
150
+ from ramifice.utils.tools import to_human_size
147
151
 
148
152
 
149
153
  @model(service_name="Accounts")
150
154
  class User:
151
155
  """Model of User."""
152
156
 
153
- def fields(self):
157
+ def fields(self) -> None:
154
158
  """For adding fields."""
155
159
  # For custom translations.
156
160
  gettext = translations.gettext
157
- ngettext = translations.ngettext
161
+ # ngettext = translations.ngettext
158
162
  self.avatar = ImageField(
159
163
  label=gettext("Avatar"),
164
+ placeholder=gettext("Upload your photo"),
160
165
  default="public/media/default/no-photo.png",
166
+ # Directory for images inside media directory.
167
+ target_dir="users/avatars",
161
168
  # Available 4 sizes from lg to xs or None.
162
169
  # Hint: By default = None
163
170
  thumbnails={"lg": 512, "md": 256, "sm": 128, "xs": 64},
@@ -166,48 +173,90 @@ class User:
166
173
  high_quality=True,
167
174
  # The maximum size of the original image in bytes.
168
175
  # Hint: By default = 2 MB
169
- max_size=524288 # 0.5 MB = 524288 Bytes (in binary)
170
- )
171
- self.resume = FileField(
172
- label=gettext("Resume"),
173
- default="public/media/default/no_doc.odt",
176
+ max_size=524288, # 512 KB = 0.5 MB = 524288 Bytes (in binary)
177
+ warning=[
178
+ gettext("Maximum size: %s" % to_human_size(524288)),
179
+ ],
174
180
  )
175
181
  self.username = TextField(
176
182
  label=gettext("Username"),
183
+ placeholder=gettext("Enter your username"),
184
+ maxlength=150,
177
185
  required=True,
178
186
  unique=True,
187
+ warning=[
188
+ gettext("Allowed chars: %s" % "a-z A-Z 0-9 _"),
189
+ ],
179
190
  )
180
191
  self.first_name = TextField(
181
- label=gettext("First name"),
182
- required=True,
192
+ label=gettext("First name"),
193
+ placeholder=gettext("Enter your First name"),
194
+ multi_language=True, # Support for several language.
195
+ maxlength=150,
196
+ required=True,
183
197
  )
184
198
  self.last_name = TextField(
185
199
  label=gettext("Last name"),
200
+ placeholder=gettext("Enter your Last name"),
201
+ multi_language=True, # Support for several language.
202
+ maxlength=150,
186
203
  required=True,
187
204
  )
188
205
  self.email = EmailField(
189
206
  label=gettext("Email"),
207
+ placeholder=gettext("Enter your email"),
190
208
  required=True,
191
209
  unique=True,
192
210
  )
211
+ self.phone = PhoneField(
212
+ label=gettext("Phone number"),
213
+ placeholder=gettext("Enter your phone number"),
214
+ unique=True,
215
+ )
193
216
  self.birthday = DateField(
194
- label=gettext("Birthday"),
217
+ label=gettext("Birthday"),
218
+ placeholder=gettext("Enter your date of birth"),
195
219
  )
196
220
  self.description = TextField(
197
- label=gettext("About yourself"),
198
- # Support for several language.
199
- multi_language=True,
221
+ label=gettext("About yourself"),
222
+ placeholder=gettext("Tell us a little about yourself ..."),
223
+ multi_language=True, # Support for several language.
200
224
  )
201
225
  self.password = PasswordField(
202
- label=gettext("Password"),
226
+ label=gettext("Password"),
227
+ placeholder=gettext("Enter your password"),
203
228
  )
204
229
  self.сonfirm_password = PasswordField(
205
230
  label=gettext("Confirm password"),
231
+ placeholder=gettext("Repeat your password"),
206
232
  # If true, the value of this field is not saved in the database.
207
233
  ignored=True,
208
234
  )
209
- self.is_admin = BooleanField(
235
+ self.is_admin = BooleanField(
210
236
  label=gettext("Is Administrator?"),
237
+ warning=[
238
+ gettext("Can this user access the admin panel?"),
239
+ ],
240
+ )
241
+ self.is_active = BooleanField(
242
+ label=gettext("Is active?"),
243
+ warning=[
244
+ gettext("Is this an active account?"),
245
+ ],
246
+ )
247
+ self.slug = SlugField(
248
+ label=gettext("Slug"),
249
+ slug_sources=["username"],
250
+ disabled=True,
251
+ hide=True,
252
+ )
253
+ self.last_login = DateTimeField(
254
+ label=gettext("Last login"),
255
+ disabled=True,
256
+ hide=True,
257
+ warning=[
258
+ gettext("Date and time of user last login."),
259
+ ],
211
260
  )
212
261
 
213
262
  # Optional method.
@@ -218,9 +267,13 @@ class User:
218
267
 
219
268
  # Get clean data.
220
269
  id = self.id.value
270
+ username = self.username.value
221
271
  password = self.password.value
222
272
  сonfirm_password = self.сonfirm_password.value
223
273
 
274
+ if re.match(r"^[a-zA-Z0-9_]+$", username) is None: # type: ignore[arg-type]
275
+ error_map["username"] = gettext("Allowed chars: %s" % "a-z A-Z 0-9 _")
276
+
224
277
  if id is None and (password != сonfirm_password):
225
278
  error_map["password"] = gettext("Passwords do not match!")
226
279
  return error_map
@@ -239,16 +292,21 @@ async def main():
239
292
  translations.change_locale("en")
240
293
 
241
294
  user = User()
295
+ # user.avatar.from_path("public/media/default/no-photo.png")
242
296
  user.username.value = "pythondev"
243
- user.avatar.from_path("public/media/default/no-photo.png")
244
- user.resume.from_path("public/media/default/no_doc.odt")
245
- user.first_name.value = "John"
246
- user.last_name.value = "Smith"
297
+ user.first_name.value = {"en": "John", "ru": "Джон"}
298
+ # user.first_name.value = "John"
299
+ user.last_name.value = {"en": "Smith", "ru": "Смит"}
300
+ # user.last_name.value = "Smith"
247
301
  user.email.value = "John_Smith@gmail.com"
302
+ user.phone.value = "+447986123456"
248
303
  user.birthday.value = datetime(2000, 1, 25)
304
+ user.description.value = {"en": "I program on Python!", "ru": "Я программирую на Python!"}
305
+ # user.description.value = "I program on Python!"
249
306
  user.password.value = "12345678"
250
307
  user.сonfirm_password.value = "12345678"
251
308
  user.is_admin.value = True
309
+ user.is_active.value = True
252
310
 
253
311
  # Create User.
254
312
  if not await user.save():
@@ -256,7 +314,7 @@ async def main():
256
314
  user.print_err()
257
315
 
258
316
  # Update User.
259
- user.username.value = "pythondev-123"
317
+ user.username.value = "pythondev_123"
260
318
  if not await user.save():
261
319
  user.print_err()
262
320
 
@@ -271,13 +329,13 @@ async def main():
271
329
  print("No User!")
272
330
 
273
331
  # Remove User.
274
- await user.delete(remove_files=False)
332
+ # (if necessary)
333
+ # await user.delete()
334
+ # await user.delete(remove_files=False)
275
335
 
276
336
  # Remove collection.
277
337
  # (if necessary)
278
- await User.collection().drop()
279
-
280
- await client.close()
338
+ # await User.collection().drop()
281
339
 
282
340
 
283
341
  if __name__ == "__main__":
@@ -45,8 +45,8 @@ 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=3426PGlJpb9ojc7gP80fd0cz5zsenvCyfgDaXAVk6FM,6963
49
- ramifice/models/pseudo.py,sha256=PhLQM4zXdaOtTSmNFzwN4twlUmdvA1D_-YOMJtaOIwM,6754
48
+ ramifice/models/model.py,sha256=MmHsb73G-h1io3EP1qy6cSOxqJ0CeaB1bzxgTT4XP_c,7113
49
+ ramifice/models/pseudo.py,sha256=0PBLHUmoT5eXzIaZtTQ20IaNUPRAuRGGfRWbUypPtfc,6765
50
50
  ramifice/paladins/__init__.py,sha256=PIP3AXI2KBRXNcLJUF0d7ygJ7VLOAxlhb4HRKQ9MGYY,516
51
51
  ramifice/paladins/check.py,sha256=ennDiVAoCZIS3aKBK0eA-Vt8VJQnbIv90be5IFYraFg,7026
52
52
  ramifice/paladins/delete.py,sha256=tw50E98D5eFZ7gHGnh_8ztUB1LeTeWWKZvIcQqlgbF8,3352
@@ -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.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,,
82
+ ramifice-0.5.2.dist-info/METADATA,sha256=8tjSGncIGRewQNVNLb6exe9yl52r92U5UFgXyl7wq1I,24388
83
+ ramifice-0.5.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
84
+ ramifice-0.5.2.dist-info/licenses/LICENSE,sha256=LrEL0aTZx90HDwFUQCJutORiDjJL9AnuVvCtspXIqt4,1095
85
+ ramifice-0.5.2.dist-info/RECORD,,