fix #409 - nullable large binary fields
This commit is contained in:
@ -59,7 +59,11 @@ class BytesDescriptor:
|
||||
def __get__(self, instance: "Model", owner: Type["Model"]) -> Any:
|
||||
value = instance.__dict__.get(self.name, None)
|
||||
field = instance.Meta.model_fields[self.name]
|
||||
if field.represent_as_base64_str and not isinstance(value, str):
|
||||
if (
|
||||
value is not None
|
||||
and field.represent_as_base64_str
|
||||
and not isinstance(value, str)
|
||||
):
|
||||
value = base64.b64encode(value).decode()
|
||||
return value
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import base64
|
||||
import uuid
|
||||
from typing import (
|
||||
Any,
|
||||
@ -51,6 +52,7 @@ class SavePrepareMixin(RelationMixin, AliasMixin):
|
||||
new_kwargs = cls._remove_not_ormar_fields(new_kwargs)
|
||||
new_kwargs = cls.substitute_models_with_pks(new_kwargs)
|
||||
new_kwargs = cls.populate_default_values(new_kwargs)
|
||||
new_kwargs = cls.reconvert_str_to_bytes(new_kwargs)
|
||||
new_kwargs = cls.translate_columns_to_aliases(new_kwargs)
|
||||
return new_kwargs
|
||||
|
||||
@ -144,6 +146,36 @@ class SavePrepareMixin(RelationMixin, AliasMixin):
|
||||
model_dict.pop(field, None)
|
||||
return model_dict
|
||||
|
||||
@classmethod
|
||||
def reconvert_str_to_bytes(cls, model_dict: Dict) -> Dict:
|
||||
"""
|
||||
Receives dictionary of model that is about to be saved and changes
|
||||
all bytes fields that are represented as strings back into bytes.
|
||||
|
||||
:param model_dict: dictionary of model that is about to be saved
|
||||
:type model_dict: Dict
|
||||
:return: dictionary of model that is about to be saved
|
||||
:rtype: Dict
|
||||
"""
|
||||
bytes_fields = {
|
||||
name
|
||||
for name, field in cls.Meta.model_fields.items()
|
||||
if field.__type__ == bytes
|
||||
}
|
||||
bytes_base64_fields = {
|
||||
name
|
||||
for name, field in cls.Meta.model_fields.items()
|
||||
if field.represent_as_base64_str
|
||||
}
|
||||
for key, value in model_dict.items():
|
||||
if key in bytes_fields and isinstance(value, str):
|
||||
model_dict[key] = (
|
||||
value.encode("utf-8")
|
||||
if key not in bytes_base64_fields
|
||||
else base64.b64decode(value)
|
||||
)
|
||||
return model_dict
|
||||
|
||||
@classmethod
|
||||
def populate_default_values(cls, new_kwargs: Dict) -> Dict:
|
||||
"""
|
||||
|
||||
@ -861,7 +861,7 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
|
||||
if column_name not in self._bytes_fields:
|
||||
return value
|
||||
field = self.Meta.model_fields[column_name]
|
||||
if not isinstance(value, bytes):
|
||||
if not isinstance(value, bytes) and value is not None:
|
||||
if field.represent_as_base64_str:
|
||||
value = base64.b64decode(value)
|
||||
else:
|
||||
@ -882,7 +882,11 @@ class NewBaseModel(pydantic.BaseModel, ModelTableProxy, metaclass=ModelMetaclass
|
||||
if column_name not in self._bytes_fields:
|
||||
return value
|
||||
field = self.Meta.model_fields[column_name]
|
||||
if not isinstance(value, str) and field.represent_as_base64_str:
|
||||
if (
|
||||
value is not None
|
||||
and not isinstance(value, str)
|
||||
and field.represent_as_base64_str
|
||||
):
|
||||
return base64.b64encode(value).decode()
|
||||
return value
|
||||
|
||||
|
||||
Reference in New Issue
Block a user