mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 07:12:01 +02:00
131 lines
3.5 KiB
Python
131 lines
3.5 KiB
Python
import logging
|
|
|
|
from marshmallow import fields
|
|
|
|
from odoo import fields as odoo_fields
|
|
|
|
from odoo.addons.datamodel.fields import NestedModel
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
__all__ = ["convert_field"]
|
|
|
|
|
|
class Binary(fields.Raw):
|
|
def _serialize(self, value, attr, obj, **kwargs):
|
|
res = super()._serialize(value, attr, obj, **kwargs)
|
|
if isinstance(res, bytes):
|
|
res = res.decode("utf-8")
|
|
return res
|
|
|
|
|
|
class FieldConverter:
|
|
def __init__(self, odoo_field):
|
|
self.odoo_field = odoo_field
|
|
|
|
def _marshmallow_field_class(self):
|
|
pass
|
|
|
|
def _get_kwargs(self):
|
|
kwargs = {
|
|
"required": self.odoo_field.required,
|
|
"allow_none": not self.odoo_field.required,
|
|
}
|
|
if self.odoo_field.readonly:
|
|
kwargs["dump_only"] = True
|
|
return kwargs
|
|
|
|
def convert_to_marshmallow(self):
|
|
marshmallow_field_class = self._marshmallow_field_class()
|
|
kwargs = self._get_kwargs()
|
|
return marshmallow_field_class(**kwargs)
|
|
|
|
|
|
class BooleanConverter(FieldConverter):
|
|
def _get_kwargs(self):
|
|
kwargs = super()._get_kwargs()
|
|
kwargs["falsy"] = fields.Boolean.falsy.union({None})
|
|
return kwargs
|
|
|
|
def _marshmallow_field_class(self):
|
|
return fields.Boolean
|
|
|
|
|
|
class IntegerConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.Integer
|
|
|
|
|
|
class FloatConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.Float
|
|
|
|
|
|
class StringConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.String
|
|
|
|
|
|
class DateConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.Date
|
|
|
|
|
|
class DatetimeConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.DateTime
|
|
|
|
|
|
class RawConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return fields.Raw
|
|
|
|
|
|
class BinaryConverter(FieldConverter):
|
|
def _marshmallow_field_class(self):
|
|
return Binary
|
|
|
|
|
|
class RelationalConverter(FieldConverter):
|
|
def _get_kwargs(self):
|
|
kwargs = super()._get_kwargs()
|
|
kwargs["many"] = isinstance(
|
|
self.odoo_field, (odoo_fields.One2many, odoo_fields.Many2many)
|
|
)
|
|
kwargs["nested"] = "generic.minimal.serializer"
|
|
kwargs["metadata"] = {"odoo_model": self.odoo_field.comodel_name}
|
|
return kwargs
|
|
|
|
def _marshmallow_field_class(self):
|
|
return NestedModel
|
|
|
|
|
|
FIELDS_CONV = {
|
|
odoo_fields.Boolean: BooleanConverter,
|
|
odoo_fields.Integer: IntegerConverter,
|
|
odoo_fields.Id: IntegerConverter,
|
|
odoo_fields.Float: FloatConverter,
|
|
odoo_fields.Monetary: FloatConverter, # should we use a Decimal instead?
|
|
odoo_fields.Char: StringConverter,
|
|
odoo_fields.Text: StringConverter,
|
|
odoo_fields.Html: StringConverter,
|
|
odoo_fields.Selection: RawConverter,
|
|
odoo_fields.Date: DateConverter,
|
|
odoo_fields.Datetime: DatetimeConverter,
|
|
odoo_fields.Binary: BinaryConverter,
|
|
odoo_fields.Image: BinaryConverter,
|
|
odoo_fields.One2many: RelationalConverter,
|
|
odoo_fields.Many2one: RelationalConverter,
|
|
odoo_fields.Many2many: RelationalConverter,
|
|
}
|
|
|
|
|
|
def convert_field(odoo_field):
|
|
field_cls = type(odoo_field)
|
|
if field_cls in FIELDS_CONV:
|
|
return FIELDS_CONV[field_cls](odoo_field).convert_to_marshmallow()
|
|
else:
|
|
_logger.warning(
|
|
"Not implemented: Odoo fields of type {} cannot be "
|
|
"translated into Marshmallow fields".format(field_cls)
|
|
)
|