Skip to content

descriptors

BytesDescriptor

Bytes descriptor converts strings to bytes on write and converts bytes to str if represent_as_base64_str flag is set, so the value can be dumped to json

Source code in ormar/models/descriptors/descriptors.py
Python
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class BytesDescriptor:
    """
    Bytes descriptor converts strings to bytes on write and converts bytes to str
    if represent_as_base64_str flag is set, so the value can be dumped to json
    """

    def __init__(self, name: str) -> None:
        self.name = name

    def __get__(self, instance: "Model", owner: type["Model"]) -> Any:
        value = instance.__dict__.get(self.name, None)
        field = instance.ormar_config.model_fields[self.name]
        if (
            value is not None
            and field.represent_as_base64_str
            and not isinstance(value, str)
        ):
            value = base64.b64encode(value).decode()
        return value

    def __set__(self, instance: "Model", value: Any) -> None:
        field = instance.ormar_config.model_fields[self.name]
        if isinstance(value, str):
            value = decode_bytes(
                value=value, represent_as_string=field.represent_as_base64_str
            )
        instance._internal_set(self.name, value)
        instance.set_save_status(False)

JsonDescriptor

Json descriptor dumps/loads strings to actual data on write/read

Source code in ormar/models/descriptors/descriptors.py
Python
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class JsonDescriptor:
    """
    Json descriptor dumps/loads strings to actual data on write/read
    """

    def __init__(self, name: str) -> None:
        self.name = name

    def __get__(self, instance: "Model", owner: type["Model"]) -> Any:
        value = instance.__dict__.get(self.name, None)
        return value

    def __set__(self, instance: "Model", value: Any) -> None:
        value = encode_json(value)
        instance._internal_set(self.name, value)
        instance.set_save_status(False)

PkDescriptor

As of now it's basically a copy of PydanticDescriptor but that will change in the future with multi column primary keys

Source code in ormar/models/descriptors/descriptors.py
Python
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class PkDescriptor:
    """
    As of now it's basically a copy of PydanticDescriptor but that will
    change in the future with multi column primary keys
    """

    def __init__(self, name: str) -> None:
        self.name = name

    def __get__(self, instance: "Model", owner: type["Model"]) -> Any:
        value = instance.__dict__.get(self.name, None)
        return value

    def __set__(self, instance: "Model", value: Any) -> None:
        instance._internal_set(self.name, value)
        instance.set_save_status(False)

PydanticDescriptor

Pydantic descriptor simply delegates everything to pydantic model

Source code in ormar/models/descriptors/descriptors.py
Python
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class PydanticDescriptor:
    """
    Pydantic descriptor simply delegates everything to pydantic model
    """

    def __init__(self, name: str) -> None:
        self.name = name

    def __get__(self, instance: "Model", owner: type["Model"]) -> Any:
        value = instance.__dict__.get(self.name, None)
        return value

    def __set__(self, instance: "Model", value: Any) -> None:
        instance._internal_set(self.name, value)
        instance.set_save_status(False)

RelationDescriptor

Relation descriptor expands the relation to initialize the related model before setting it to dict. Note that expanding also registers the related model in RelationManager.

Source code in ormar/models/descriptors/descriptors.py
Python
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class RelationDescriptor:
    """
    Relation descriptor expands the relation to initialize the related model
    before setting it to __dict__. Note that expanding also registers the
    related model in RelationManager.
    """

    def __init__(self, name: str) -> None:
        self.name = name

    def __get__(self, instance: "Model", owner: type["Model"]) -> Any:
        if self.name in instance._orm:
            return instance._orm.get(self.name)  # type: ignore
        return None  # pragma no cover

    def __set__(self, instance: "Model", value: Any) -> None:
        field = instance.ormar_config.model_fields[self.name]
        field.expand_relationship(value=value, child=instance)

        if (
            value is None
            and field.nullable
            and not field.virtual
            and not field.is_multi
            and self.name in instance._orm
        ):
            previous = cast(Optional["Model"], instance._orm.get(self.name))
            if previous is not None:
                instance._orm.remove(self.name, previous)

        if not isinstance(instance.__dict__.get(self.name), list):
            instance.set_save_status(False)