xn-model 1.0.12__py3-none-any.whl → 1.0.14__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.
- x_model/models.py +41 -29
- x_model/types.py +6 -11
- {xn_model-1.0.12.dist-info → xn_model-1.0.14.dist-info}/METADATA +2 -1
- xn_model-1.0.14.dist-info/RECORD +9 -0
- {xn_model-1.0.12.dist-info → xn_model-1.0.14.dist-info}/WHEEL +1 -1
- xn_model-1.0.12.dist-info/RECORD +0 -9
- {xn_model-1.0.12.dist-info → xn_model-1.0.14.dist-info}/top_level.txt +0 -0
x_model/models.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
from dataclasses import make_dataclass, field, fields
|
|
1
2
|
from datetime import datetime
|
|
2
3
|
from typing import Self
|
|
3
4
|
|
|
4
|
-
from pydantic import ConfigDict
|
|
5
|
+
from pydantic import ConfigDict
|
|
5
6
|
from tortoise import Model as TortModel
|
|
6
|
-
from tortoise.contrib.pydantic import pydantic_model_creator, PydanticModel
|
|
7
7
|
from tortoise.fields import IntField
|
|
8
8
|
|
|
9
9
|
from x_model.field import DatetimeSecField
|
|
10
|
+
from x_model.types import BaseUpd
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class TsTrait:
|
|
@@ -17,37 +18,53 @@ class TsTrait:
|
|
|
17
18
|
class Model(TortModel):
|
|
18
19
|
id: int = IntField(True)
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
_in_type: type[BaseModel] = None # overridable
|
|
21
|
+
_in_type: type[BaseUpd] = None # overridable
|
|
22
22
|
_name: tuple[str] = ("name",)
|
|
23
23
|
_sorts: tuple[str] = ("-id",)
|
|
24
24
|
|
|
25
25
|
def __repr__(self, sep: str = " ") -> str:
|
|
26
26
|
return sep.join(getattr(self, name_fragment) for name_fragment in self._name)
|
|
27
27
|
|
|
28
|
-
@classmethod
|
|
29
|
-
def out_type(cls):
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
# @classmethod
|
|
29
|
+
# def out_type(cls) -> type[BaseModel]:
|
|
30
|
+
# if not cls._out_type:
|
|
31
|
+
# cls._out_type = pydantic_model_creator(cls, name=cls.__name__ + "Out")
|
|
32
|
+
# return cls._out_type
|
|
33
33
|
|
|
34
34
|
@classmethod
|
|
35
|
-
def in_type(cls):
|
|
36
|
-
if not cls
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
35
|
+
def in_type(cls, with_pk: bool = False) -> type[BaseUpd]:
|
|
36
|
+
if not getattr(cls, cn := "Upd" if with_pk else "New", None):
|
|
37
|
+
fields: list[tuple[str, type] | tuple[str, type, field]] = []
|
|
38
|
+
for fn in cls._meta.db_fields:
|
|
39
|
+
if (f := cls._meta.fields_map[fn]).pk and not with_pk:
|
|
40
|
+
continue
|
|
41
|
+
if getattr(f, "auto_now", None) or getattr(f, "auto_now_add", None):
|
|
42
|
+
continue
|
|
43
|
+
fld = fn, getattr(f, "enum_type", f.field_type)
|
|
44
|
+
if f.default or f.null or (f.allows_generated and not f.pk) or not f.required:
|
|
45
|
+
fld += (field(default_factory=dict) if f.default == {} else field(default=f.default),)
|
|
46
|
+
fields.append(fld)
|
|
47
|
+
# for fn in cls._meta.fk_fields:
|
|
48
|
+
# f = cls._meta.fields_map[fn]
|
|
49
|
+
# fld = fn+"_id", int
|
|
50
|
+
# if f.default or f.allows_generated or f.null or not f.required:
|
|
51
|
+
# fld += (field(default=f.default),)
|
|
52
|
+
# fields.append(fld)
|
|
53
|
+
|
|
54
|
+
dcl = make_dataclass(cls.__name__ + cn, fields, bases=(BaseUpd,), kw_only=True)
|
|
55
|
+
dcl._unq = (cls._meta.unique_together or ((),))[0]
|
|
56
|
+
if with_pk:
|
|
57
|
+
dcl._unq += ("id",)
|
|
58
|
+
setattr(cls, cn, dcl)
|
|
59
|
+
|
|
60
|
+
return getattr(cls, cn)
|
|
41
61
|
|
|
42
62
|
# # # CRUD Methods # # #
|
|
43
63
|
@classmethod
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
async def one(self) -> PydanticModel:
|
|
50
|
-
return await self.out_type().from_tortoise_orm(self)
|
|
64
|
+
def validate(cls, dct: dict) -> BaseUpd:
|
|
65
|
+
dcl = cls.in_type("id" in dct)
|
|
66
|
+
field_names = [n.name for n in fields(dcl)]
|
|
67
|
+
return dcl(**{k: v for k, v in dct.items() if k in field_names})
|
|
51
68
|
|
|
52
69
|
@classmethod
|
|
53
70
|
async def get_or_create_by_name(cls, name: str, attr_name: str = None, def_dict: dict = None) -> Self:
|
|
@@ -62,17 +79,12 @@ class Model(TortModel):
|
|
|
62
79
|
# include: tuple[str, ...] = ()
|
|
63
80
|
# exclude: tuple[str, ...] = ("Meta",)
|
|
64
81
|
# computed: tuple[str, ...] = ()
|
|
65
|
-
|
|
82
|
+
backward_relations: bool = False # True
|
|
66
83
|
max_recursion: int = 1 # default: 3
|
|
67
84
|
# allow_cycles: bool = False
|
|
68
|
-
# exclude_raw_fields: bool = True
|
|
85
|
+
# exclude_raw_fields: bool = False # True
|
|
69
86
|
# sort_alphabetically: bool = False
|
|
70
87
|
# model_config: ConfigDict | None = None
|
|
71
88
|
|
|
72
|
-
class PydanticMetaIn:
|
|
73
|
-
backward_relations: bool = False
|
|
74
|
-
max_recursion: int = 0
|
|
75
|
-
exclude_raw_fields: bool = False
|
|
76
|
-
|
|
77
89
|
class Meta:
|
|
78
90
|
abstract = True
|
x_model/types.py
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
|
+
from dataclasses import dataclass, asdict
|
|
1
2
|
from typing import ClassVar
|
|
2
|
-
from pydantic import BaseModel
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
@dataclass
|
|
6
|
+
class BaseUpd:
|
|
7
|
+
_unq: ClassVar[tuple[str]]
|
|
7
8
|
|
|
8
9
|
def df_unq(self) -> dict:
|
|
9
|
-
d = {k: v for k, v in self
|
|
10
|
-
return {**{k: d.pop(k, None) for k in
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class Upd(New):
|
|
14
|
-
_unq = ("id",)
|
|
15
|
-
|
|
16
|
-
id: int
|
|
10
|
+
d = {k: v for k, v in asdict(self).items() if v is not None or k in self._unq}
|
|
11
|
+
return {**{k: d.pop(k, None) for k in self._unq}, "defaults": d}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: xn-model
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.14
|
|
4
4
|
Summary: Base model for xn-api
|
|
5
5
|
Author-email: Mike Artemiev <mixartemev@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -10,6 +10,7 @@ Keywords: tortoise,model,crud,generator,api,admin
|
|
|
10
10
|
Requires-Python: >=3.11
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
Requires-Dist: tortoise-orm[asyncpg]
|
|
13
|
+
Requires-Dist: pydantic
|
|
13
14
|
Provides-Extra: dev
|
|
14
15
|
Requires-Dist: pytest; extra == "dev"
|
|
15
16
|
Requires-Dist: python-dotenv; extra == "dev"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
x_model/__init__.py,sha256=JRsYD3P-8pHpEkCUgy6GuodkT7ZaY1AEeEK1CbpgZw4,428
|
|
2
|
+
x_model/field.py,sha256=zVszcPZFVEwsurqbFQF-_caiSLruh3TRSZdgQqwWJV8,2776
|
|
3
|
+
x_model/func.py,sha256=E7jDoHJGaFpKvxbHnT_lyBxUZeMo-GRd5gv9dLw7B9s,289
|
|
4
|
+
x_model/models.py,sha256=EmudSEdcxsydnj6OyqnA1xdAVPhxRUN79610ncLpPXw,3544
|
|
5
|
+
x_model/types.py,sha256=sF-j-IzL00as74pnQbjdDC82oKJlbpxzoAvbE7KDCHs,320
|
|
6
|
+
xn_model-1.0.14.dist-info/METADATA,sha256=2CXAIifJuvL-0QoVum0pZcYSXvWHg3HYyRZOMpQlDo8,986
|
|
7
|
+
xn_model-1.0.14.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
8
|
+
xn_model-1.0.14.dist-info/top_level.txt,sha256=QCYyfv5AA_8jPPtCpShkBXzQRUCGuuW7Ro0mqysDE8E,8
|
|
9
|
+
xn_model-1.0.14.dist-info/RECORD,,
|
xn_model-1.0.12.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
x_model/__init__.py,sha256=JRsYD3P-8pHpEkCUgy6GuodkT7ZaY1AEeEK1CbpgZw4,428
|
|
2
|
-
x_model/field.py,sha256=zVszcPZFVEwsurqbFQF-_caiSLruh3TRSZdgQqwWJV8,2776
|
|
3
|
-
x_model/func.py,sha256=E7jDoHJGaFpKvxbHnT_lyBxUZeMo-GRd5gv9dLw7B9s,289
|
|
4
|
-
x_model/models.py,sha256=-dhEPBoOIcMvkWayjgOBt9xYiOalv8ZIM9bmFziVdzM,2710
|
|
5
|
-
x_model/types.py,sha256=u3oYmN1g2BpPUvmvPowuNh1lL3z4zJroJKsGre5Yxds,352
|
|
6
|
-
xn_model-1.0.12.dist-info/METADATA,sha256=3-hj5vYl54hSa71r0Vfp8jVsCSz0naer2Jjtkc4DgCY,962
|
|
7
|
-
xn_model-1.0.12.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
|
|
8
|
-
xn_model-1.0.12.dist-info/top_level.txt,sha256=QCYyfv5AA_8jPPtCpShkBXzQRUCGuuW7Ro0mqysDE8E,8
|
|
9
|
-
xn_model-1.0.12.dist-info/RECORD,,
|
|
File without changes
|