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 +3 -1
- ramifice/models/pseudo.py +1 -1
- {ramifice-0.5.0.dist-info → ramifice-0.5.2.dist-info}/METADATA +85 -27
- {ramifice-0.5.0.dist-info → ramifice-0.5.2.dist-info}/RECORD +6 -6
- {ramifice-0.5.0.dist-info → ramifice-0.5.2.dist-info}/WHEEL +0 -0
- {ramifice-0.5.0.dist-info → ramifice-0.5.2.dist-info}/licenses/LICENSE +0 -0
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
|
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
|
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.
|
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
|
170
|
-
|
171
|
-
|
172
|
-
|
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
|
-
|
182
|
-
|
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
|
-
|
217
|
+
label=gettext("Birthday"),
|
218
|
+
placeholder=gettext("Enter your date of birth"),
|
195
219
|
)
|
196
220
|
self.description = TextField(
|
197
|
-
|
198
|
-
|
199
|
-
|
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
|
-
|
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
|
-
|
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.
|
244
|
-
user.
|
245
|
-
user.
|
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 = "
|
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
|
-
|
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=
|
49
|
-
ramifice/models/pseudo.py,sha256=
|
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.
|
83
|
-
ramifice-0.5.
|
84
|
-
ramifice-0.5.
|
85
|
-
ramifice-0.5.
|
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,,
|
File without changes
|
File without changes
|