Code source de geonature.core.gn_commons.schemas

import logging
from marshmallow import Schema, pre_load, fields, EXCLUDE

from utils_flask_sqla.schema import SmartRelationshipsMixin

from pypnnomenclature.schemas import NomenclatureSchema, BibNomenclaturesTypesSchema

from pypnusershub.schemas import UserSchema
from geonature.utils.env import MA
from geonature.core.gn_commons.models import (
    TModules,
    TMedias,
    TValidations,
    TAdditionalFields,
    BibWidgets,
)
from geonature.core.gn_permissions.schemas import PermObjectSchema


[docs] log = logging.getLogger()
[docs] class ModuleSchema(MA.SQLAlchemyAutoSchema):
[docs] class Meta:
[docs] model = TModules
[docs] load_instance = True
[docs] exclude = ( "module_picto", "module_desc", "module_group", "module_external_url", "module_target", "module_comment", "active_frontend", "active_backend", "module_doc_url", "module_order", )
[docs] class MediaSchema(MA.SQLAlchemyAutoSchema):
[docs] class Meta:
[docs] model = TMedias
[docs] load_instance = True
[docs] include_fk = True
[docs] unknown = EXCLUDE
[docs] meta_create_date = fields.DateTime(dump_only=True)
[docs] meta_update_date = fields.DateTime(dump_only=True)
@pre_load
[docs] def make_media(self, data, **kwargs): if data.get("id_media") is None: data.pop("id_media", None) return data
[docs] class TValidationSchema(MA.SQLAlchemyAutoSchema):
[docs] class Meta:
[docs] model = TValidations
[docs] load_instance = True
[docs] include_fk = True
[docs] validation_label = fields.Nested(NomenclatureSchema, dump_only=True)
[docs] validator_role = MA.Nested(UserSchema, dump_only=True)
[docs] class BibWidgetSchema(MA.SQLAlchemyAutoSchema):
[docs] class Meta:
[docs] model = BibWidgets
[docs] load_instance = True
[docs] class LabelValueDict(Schema):
[docs] label = fields.Str()
[docs] value = fields.Raw()
[docs] class CastableField(fields.Field): """ A field which tries to cast the value to int or float before returning it. If the value is not castable, the default value is returned. """
[docs] def _serialize(self, value, attr, obj, **kwargs): if value: try: value = float(value) except ValueError: log.warning("default value not castable to float") try: value = int(value) except ValueError: log.warning("default value not castable to int") return value
[docs] class TAdditionalFieldsSchema(SmartRelationshipsMixin, MA.SQLAlchemyAutoSchema):
[docs] class Meta:
[docs] model = TAdditionalFields
[docs] load_instance = True
[docs] default_value = CastableField(allow_none=True)
[docs] code_nomenclature_type = fields.Str(allow_none=True)
[docs] modules = fields.Nested(ModuleSchema, many=True, dump_only=True)
[docs] objects = fields.Nested(PermObjectSchema, many=True, dump_only=True)
[docs] type_widget = fields.Nested(BibWidgetSchema, dump_only=True)
[docs] datasets = fields.Nested("DatasetSchema", many=True, dump_only=True)
[docs] bib_nomenclature_type = fields.Nested(BibNomenclaturesTypesSchema, dump_only=True)
[docs] def load(self, data, *, many=None, **kwargs): if data["type_widget"].widget_name in ( "select", "checkbox", "radio", "multiselect", ): LabelValueDict(many=True).load(data["field_values"]) return super().load(data, many=many, unknown=EXCLUDE)