model.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import tortoise.models
  2. from .field_generator import field_generator
  3. from .constants import constants
  4. from .exceptions import not_exists
  5. class model(tortoise.models.Model):
  6. """
  7. This is base class for all models in the app. It store base fields, like
  8. ID, and have functions, which is necessary to validate object before
  9. save it in the database.
  10. Fields
  11. ------
  12. id : field_generator.id
  13. ID of the object.
  14. Methods
  15. -------
  16. _validators : dict
  17. Return dict of validators, which would be used to validate fields of
  18. the object. For example, when object have field "name", and function
  19. "val_name(name: str) -> str" would be used to validate it, then that
  20. dict must contain "{ 'name': val_name }".
  21. __validate_item : None
  22. That validate sinle item of the object. To pass validation, result
  23. from validating function must be same as before validaion, and that
  24. function must not raise and error.
  25. __get : any
  26. That return content of given field of object.
  27. validate : object
  28. That run all validators. When any validators found problem with
  29. content of object, then raise an ValueError. If all went nice, then
  30. return self.
  31. Classes
  32. -------
  33. Meta
  34. Fields
  35. ------
  36. app : str
  37. Name of the app.
  38. """
  39. id = field_generator.id()
  40. def __repr__(self) -> str:
  41. result = "Dump of " + self.__class__.__name__
  42. if self.id is not None:
  43. result = result + " #" + str(self.id)
  44. result = result + "\n"
  45. for count in dir(self):
  46. if count[0] == "_":
  47. continue
  48. if count == "id":
  49. continue
  50. if count == "pk":
  51. continue
  52. field = self.__getattribute__(count)
  53. if type(field) is str:
  54. result = result + " " + count + ": \"" + field + "\"\n"
  55. continue
  56. if type(field) is int or type(field) is float:
  57. result = result + " " + count + ": " + str(field) + "\n"
  58. continue
  59. if type(field) is bool:
  60. result = result + " " + count + ": " + str(field) + "\n"
  61. continue
  62. return result
  63. def _validators(self) -> dict:
  64. """
  65. That return dict of fields, which must be validated, with validators
  66. which must be used. Format of the dict is "{ 'name of the field':
  67. validation_function }". By default it is empty, and none of the field
  68. is not validating.
  69. Returns
  70. -------
  71. dict
  72. Dictionary with validators for fields.
  73. """
  74. return dict()
  75. def __validate_item(self, validator: callable, key: str) -> None:
  76. """
  77. It validate single field of the object. When validation is passed,
  78. it return without errors, in other way it raise ValueError.
  79. Parameters
  80. ----------
  81. validator : callable
  82. Validator which would be used to validate field.
  83. key : str
  84. Name of the field.
  85. Raises
  86. ------
  87. ValueError
  88. When field contain incorrect data.
  89. """
  90. try:
  91. if validator(self.__get(key)) == self.__get(key):
  92. return
  93. raise ValueError("Validated value is not same.")
  94. except Exception as error:
  95. value = self.__get(key)
  96. model_name = type(self).__name__
  97. info = "Model \"" + model_name + "\" contain invalid "
  98. info = info + "data in field \"" + key + "\". Content of "
  99. info = info + "field is \"" + value + "\". Found error \""
  100. info = info + str(error) + "\"."
  101. raise ValueError(info)
  102. def __get(self, key: str) -> any:
  103. """
  104. That return field with given name.
  105. Parameters
  106. ----------
  107. key : str
  108. Name of the field.
  109. Returns
  110. -------
  111. any
  112. Value of the key.
  113. """
  114. return self.__getattribute__(key)
  115. async def get_related(
  116. self,
  117. target_model: type | str,
  118. target_field: str
  119. ) -> any:
  120. """
  121. That load models related to that model. It require name of
  122. the related model, and field which is related to that model.
  123. Parameters
  124. ----------
  125. target_model : type | str
  126. Target model which has relation with.
  127. target_model : str
  128. Field which use that relation.
  129. Returns
  130. -------
  131. any
  132. Models which is related to given parameters.
  133. """
  134. related_name = constants.get_related_name(
  135. target_model,
  136. target_field
  137. )
  138. return await self.fetch_related(related_name)
  139. def validate(self) -> object:
  140. """
  141. That function make full validation of the object. It validate all
  142. fields, which is in the __validators() dict. When validation had
  143. been passed, it return self. When validation couldn't being passed
  144. it raises ValueError.
  145. Returns
  146. -------
  147. model
  148. Object instance itself.
  149. Raises
  150. ------
  151. ValueError
  152. When any field contain incorrect data.
  153. """
  154. for key, validator in self._validators().items():
  155. self.__validate_item(validator, key)
  156. return self
  157. def is_in_database(self) -> bool:
  158. """
  159. This function return that model is in the database
  160. or not.
  161. Returns
  162. -------
  163. bool
  164. True when objects exists in database, False when not.
  165. """
  166. return self.id is not None
  167. def get_identifier(self) -> int:
  168. """
  169. That return currently identifier of the object, or raise error
  170. when object not exists.
  171. Raises
  172. ------
  173. not_exists
  174. When object not exists yet.
  175. Returns
  176. -------
  177. int
  178. Identifier of the object.
  179. """
  180. if not self.is_in_database():
  181. raise not_exists(self)
  182. return self.id
  183. class Meta:
  184. app = constants.app_name()