xn-model 1.0.13__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 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, BaseModel
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
- _out_type: type[BaseModel] = None # overridable
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
- if not cls._out_type:
31
- cls._out_type = pydantic_model_creator(cls, name=cls.__name__ + "Out")
32
- return cls._out_type
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._in_type:
37
- cls._in_type = pydantic_model_creator(
38
- cls, name=cls.__name__ + "In", exclude_readonly=True, meta_override=cls.PydanticMetaIn
39
- )
40
- return cls._in_type
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
- async def get_one(cls, id_: int) -> PydanticModel:
45
- if obj := await cls.get_or_none(id=id_):
46
- return await cls.out_type().from_tortoise_orm(obj)
47
- raise LookupError(f"{cls.__name__}#{id_} not found")
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
- # backward_relations: bool = True
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
- class New(BaseModel):
6
- _unq: ClassVar[tuple[str]] = ()
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.model_dump(exclude_none=True).items()}
10
- return {**{k: d.pop(k, None) for k in set(self._unq)}, "defaults": d}
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.13
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
@@ -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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.0.2)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -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.13.dist-info/METADATA,sha256=XflOvAKouEejL9Wk_MgHPJC3igDXQFnd28yReDKSNq0,986
7
- xn_model-1.0.13.dist-info/WHEEL,sha256=DK49LOLCYiurdXXOXwGJm6U4DkHkg4lcxjhqwRa0CP4,91
8
- xn_model-1.0.13.dist-info/top_level.txt,sha256=QCYyfv5AA_8jPPtCpShkBXzQRUCGuuW7Ro0mqysDE8E,8
9
- xn_model-1.0.13.dist-info/RECORD,,