Skip to content

xsdata serialization with a computed field #1229

Description

@erwandrezen

I am currently struggling with pydantic and xsdata serialization. I have the following classes:

from pydantic import BaseModel, ConfigDict, computed_field
from xsdata_pydantic.fields import field

class BaseModelWithType(BaseModel):
    model_config = ConfigDict(defer_build=True)
    @computed_field
    def type(self) -> str :
      return type(self).__name__

class SomeClass(BaseModelWithType):
    model_config = ConfigDict(defer_build=True)
    some_field: str  = field(
        metadata={
            "name": "someField",
            "type": "Attribute",
        }
    )

where

  1. BaseModelWithType defines a computed field that returns type information of the underlying object and
  2. SomeClass (inheriting from BaseModelWithType) that provides some_field. Note that this field provides some metadata information and in particular a name

Now, I can define an object like this

obj = SomeClass(some_field="NAME")

and serialize it with pydantic as follows:

print(obj.model_dump_json())

which gives the following:

{"some_field":"NAME","type":"SomeClass"}

On the other hand, if I use a serializer from xsdata with this:

json_serializer = JsonSerializer(context=XmlContext(class_type="pydantic"), config=SerializerConfig())
print(json_serializer.render(obj))

I get the following where the metadata someField is used but the computed field type is not present

{"someField": "NAME"}

In the end, I would like to have both the computed field and use the metadata information, i.e.

{"someField":"NAME","type":"SomeClass"}

but I don't see how to do this, and I am not even sure it can be done.

Note: It might be a XY problem. What I want to do is to add some typing information for some classes generated by xsdata. This extra type information is not generated by default but I need it since the json generation has to be reused in another context (in java) where this type information is required.

The full snippet is

from pydantic import BaseModel, ConfigDict, computed_field
from xsdata_pydantic.fields import field
from xsdata.formats.dataclass.serializers import JsonSerializer
from xsdata.formats.dataclass.context import XmlContext
from xsdata.formats.dataclass.serializers.config import SerializerConfig

class BaseModelWithType(BaseModel):
    model_config = ConfigDict(defer_build=True)
    @computed_field
    def type(self) -> str :
      return type(self).__name__

class SomeClass(BaseModelWithType):
    model_config = ConfigDict(defer_build=True)
    some_field: str  = field(
        metadata={
            "name": "someField",
            "type": "Attribute",
        }
    )

obj = SomeClass(some_field="NAME")

print(obj.model_dump_json())
json_serializer = JsonSerializer(context=XmlContext(class_type="pydantic"), config=SerializerConfig())
print(json_serializer.render(obj))

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions