more optimizations

This commit is contained in:
collerek
2020-12-02 20:39:30 +01:00
parent 3e615a8057
commit 4e10ff03e2
3 changed files with 138 additions and 109 deletions

View File

@ -336,27 +336,51 @@ def add_cached_properties(new_model):
prop
for prop in vars(new_model)
if isinstance(getattr(new_model, prop), property)
and prop
not in ("__values__", "__fields__", "fields", "pk_column", "saved")
and prop not in ("__values__", "__fields__", "fields", "pk_column", "saved")
}
new_model._quick_access_fields = {
"_orm_id",
"_orm_saved",
"_orm",
"_convert_json",
"__fields__",
"_related_names",
"_props",
"__class__",
"__dict__",
"__config__",
"_iter",
"_get_value",
"_is_conversion_to_json_needed",
"__fields_set__",
"_skip_ellipsis",
"_calculate_keys",
"dict",
"_update_excluded_with_related_not_required",
"_extract_nested_models",
"_get_related_not_excluded_fields",
"get_properties",
"resolve_relation_name",
"resolve_relation_field",
"set_save_status",
"__pre_root_validators__",
"__post_root_validators__",
"_extract_nested_models_from_list",
"get_name",
"extract_related_names",
"Meta",
}
new_model._related_names = None
new_model._pydantic_fields = {name for name in new_model.__fields__}
def add_property_fields(new_model):
if new_model.Meta.include_props_in_fields:
for prop in new_model._props:
field_type = getattr(new_model, prop).fget.__annotations__.get('return')
new_model.Meta.model_fields[prop] = ModelFieldFactory(nullable=True, pydantic_only=True)
field_type = getattr(new_model, prop).fget.__annotations__.get("return")
new_model.Meta.model_fields[prop] = ModelFieldFactory(
nullable=True, pydantic_only=True
)
new_model.__fields__[prop] = ModelField(
name=prop,
type_=Optional[field_type] if field_type else Any,

View File

@ -1,5 +1,6 @@
import json
import uuid
from collections import Counter
from typing import (
AbstractSet,
Any,
@ -155,24 +156,25 @@ class NewBaseModel(
self.set_save_status(False)
def __getattribute__(self, item: str) -> Any:
if item in object.__getattribute__(self, '_quick_access_fields'):
if item in object.__getattribute__(self, "_quick_access_fields"):
return object.__getattribute__(self, item)
if item == "pk":
return self.__dict__.get(self.Meta.pkname, None)
if item in self.extract_related_names():
return self._extract_related_model_instead_of_field(item)
if item in self._props:
return object.__getattribute__(self, "__dict__").get(self.Meta.pkname, None)
if item in object.__getattribute__(self, "extract_related_names")():
return object.__getattribute__(
self, "_extract_related_model_instead_of_field"
)(item)
if item in object.__getattribute__(self, "_props"):
return object.__getattribute__(self, item)
if item in self.__fields__:
value = self.__dict__.get(item, None)
value = self._convert_json(item, value, "loads")
if item in object.__getattribute__(self, "_pydantic_fields"):
value = object.__getattribute__(self, "__dict__").get(item, None)
value = object.__getattribute__(self, "_convert_json")(item, value, "loads")
return value
return super().__getattribute__(item)
return object.__getattribute__(self, item)
def _extract_related_model_instead_of_field(
self, item: str
) -> Optional[Union["T", Sequence["T"]]]:
# alias = self.get_column_alias(item)
if item in self._orm:
return self._orm.get(item)
return None # pragma no cover
@ -185,8 +187,8 @@ class NewBaseModel(
def __same__(self, other: "NewBaseModel") -> bool:
return (
self._orm_id == other._orm_id
or self.dict() == other.dict()
or (self.pk == other.pk and self.pk is not None)
or self.dict() == other.dict()
)
@classmethod
@ -254,7 +256,7 @@ class NewBaseModel(
for model in models:
try:
result.append(
model.dict(nested=True, include=include, exclude=exclude, )
model.dict(nested=True, include=include, exclude=exclude,)
)
except ReferenceError: # pragma no cover
continue
@ -363,4 +365,7 @@ class NewBaseModel(
return value
def _is_conversion_to_json_needed(self, column_name: str) -> bool:
return column_name in self.Meta.model_fields and self.Meta.model_fields[column_name].__type__ == pydantic.Json
return (
column_name in self.Meta.model_fields
and self.Meta.model_fields[column_name].__type__ == pydantic.Json
)