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 prop
for prop in vars(new_model) for prop in vars(new_model)
if isinstance(getattr(new_model, prop), property) if isinstance(getattr(new_model, prop), property)
and prop and prop not in ("__values__", "__fields__", "fields", "pk_column", "saved")
not in ("__values__", "__fields__", "fields", "pk_column", "saved")
} }
new_model._quick_access_fields = { new_model._quick_access_fields = {
"_orm_id", "_orm_id",
"_orm_saved", "_orm_saved",
"_orm", "_orm",
"_convert_json",
"__fields__", "__fields__",
"_related_names", "_related_names",
"_props", "_props",
"__class__", "__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", "extract_related_names",
"Meta",
} }
new_model._related_names = None new_model._related_names = None
new_model._pydantic_fields = {name for name in new_model.__fields__}
def add_property_fields(new_model): def add_property_fields(new_model):
if new_model.Meta.include_props_in_fields: if new_model.Meta.include_props_in_fields:
for prop in new_model._props: for prop in new_model._props:
field_type = getattr(new_model, prop).fget.__annotations__.get('return') field_type = getattr(new_model, prop).fget.__annotations__.get("return")
new_model.Meta.model_fields[prop] = ModelFieldFactory(nullable=True, pydantic_only=True) new_model.Meta.model_fields[prop] = ModelFieldFactory(
nullable=True, pydantic_only=True
)
new_model.__fields__[prop] = ModelField( new_model.__fields__[prop] = ModelField(
name=prop, name=prop,
type_=Optional[field_type] if field_type else Any, type_=Optional[field_type] if field_type else Any,

View File

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