52 lines
1.6 KiB
Python
52 lines
1.6 KiB
Python
from typing import Dict, Self, Any, get_origin
|
|
from dataclasses import fields, Field
|
|
|
|
|
|
class OdooModel:
|
|
@classmethod
|
|
def specification(cls) -> Dict[str, Any]:
|
|
def field_spec(f: Field) -> Dict[str, Any]:
|
|
field_type = f.type
|
|
if f.name.endswith("_id") or f.name.endswith("_ids"):
|
|
return {
|
|
f.name: {
|
|
"fields": {
|
|
"display_name": {},
|
|
},
|
|
},
|
|
}
|
|
elif field_type in {str, int, bool}:
|
|
return {f.name: {}}
|
|
else:
|
|
raise NotImplementedError(f"Unsupported field type: {field_type}")
|
|
|
|
spec = dict()
|
|
for f in fields(cls):
|
|
if f.init:
|
|
spec.update(field_spec(f))
|
|
|
|
return spec
|
|
|
|
@classmethod
|
|
def from_record(cls, record: Dict) -> Self:
|
|
init_args = {}
|
|
for f in fields(cls):
|
|
if f.init and f.name in record:
|
|
value = record[f.name]
|
|
|
|
if f.name.endswith("_id"):
|
|
if f.type is str:
|
|
value = value["display_name"]
|
|
else:
|
|
raise NotImplementedError()
|
|
|
|
if f.name.endswith("_ids"):
|
|
if get_origin(f.type) is list and f.type.__args__[0] is str:
|
|
value = [v["display_name"] for v in value]
|
|
else:
|
|
raise NotImplementedError()
|
|
|
|
init_args[f.name] = value
|
|
|
|
return cls(**init_args)
|