98 lines
4.1 KiB
Python
98 lines
4.1 KiB
Python
import pydantic
|
|
|
|
from ormar.models.helpers.validation import validate_choices
|
|
|
|
|
|
class PydanticDescriptor:
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __get__(self, instance, owner):
|
|
value = object.__getattribute__(instance, "__dict__").get(self.name, None)
|
|
value = object.__getattribute__(instance, "_convert_json")(self.name, value,
|
|
"loads")
|
|
value = object.__getattribute__(instance, "_convert_bytes")(self.name, value,
|
|
"read")
|
|
return value
|
|
|
|
def __set__(self, instance, value):
|
|
if self.name in object.__getattribute__(instance, "_choices_fields"):
|
|
validate_choices(field=instance.Meta.model_fields[self.name], value=value)
|
|
value = object.__getattribute__(instance, '_convert_bytes')(self.name, value,
|
|
op="write")
|
|
value = object.__getattribute__(instance, '_convert_json')(self.name, value,
|
|
op="dumps")
|
|
super(instance.__class__, instance).__setattr__(self.name, value)
|
|
object.__getattribute__(instance, "set_save_status")(False)
|
|
|
|
|
|
class PkDescriptor:
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __get__(self, instance, owner):
|
|
value = object.__getattribute__(instance, "__dict__").get(self.name, None)
|
|
value = object.__getattribute__(instance, "_convert_json")(self.name, value,
|
|
"loads")
|
|
value = object.__getattribute__(instance, "_convert_bytes")(self.name, value,
|
|
"read")
|
|
return value
|
|
|
|
def __set__(self, instance, value):
|
|
if self.name in object.__getattribute__(instance, "_choices_fields"):
|
|
validate_choices(field=instance.Meta.model_fields[self.name], value=value)
|
|
value = object.__getattribute__(instance, '_convert_bytes')(self.name, value,
|
|
op="write")
|
|
value = object.__getattribute__(instance, '_convert_json')(self.name, value,
|
|
op="dumps")
|
|
super(instance.__class__, instance).__setattr__(self.name, value)
|
|
object.__getattribute__(instance, "set_save_status")(False)
|
|
|
|
|
|
class RelationDescriptor:
|
|
|
|
def __init__(self, name):
|
|
self.name = name
|
|
|
|
def __get__(self, instance, owner):
|
|
if self.name in object.__getattribute__(instance, '_orm'):
|
|
return object.__getattribute__(instance, '_orm').get(
|
|
self.name) # type: ignore
|
|
return None # pragma no cover
|
|
|
|
def __set__(self, instance, value):
|
|
model = (
|
|
object.__getattribute__(instance, "Meta")
|
|
.model_fields[self.name]
|
|
.expand_relationship(value=value, child=instance)
|
|
)
|
|
if isinstance(object.__getattribute__(instance, "__dict__").get(self.name),
|
|
list):
|
|
# virtual foreign key or many to many
|
|
# TODO: Fix double items in dict, no effect on real action ugly repr
|
|
# if model.pk not in [x.pk for x in related_list]:
|
|
object.__getattribute__(instance, "__dict__")[self.name].append(model)
|
|
else:
|
|
# foreign key relation
|
|
object.__getattribute__(instance, "__dict__")[self.name] = model
|
|
object.__getattribute__(instance, "set_save_status")(False)
|
|
|
|
|
|
class PropertyDescriptor:
|
|
|
|
def __init__(self, name, function):
|
|
self.name = name
|
|
self.function = function
|
|
|
|
def __get__(self, instance, owner):
|
|
if instance is None:
|
|
return self
|
|
if instance is not None and self.function is not None:
|
|
bound = self.function.__get__(instance, instance.__class__)
|
|
return bound() if callable(bound) else bound
|
|
|
|
def __set__(self, instance, value):
|
|
pass
|