Skip to content

Serialization and rendering #15

Description

@mjtamlyn

Serialization is strictly the process of getting from a rich object to a bytestring (encoded in some format). Forms in particular make that bytestring rather complicated, and the deserialization step is funky. I'm not sure of the "right" terminology but I think we should think about two separate steps.

Firstly, we want to deconstruct and normalise our data set to a small subset of types. Some of these types are obvious - list, dict, str, int, float, bool, NoneType etc. Some are less clear whether they should be supported at this level - for example decimal.Decimal, collections.OrderedDict, datetime.datetime, set, or even more domain specific types like prices.Price. It's hard to know where to draw the line here - there's no perfect common set of data types which are supported by all possible encodings (renderers). Given that the HTMLForm/x-www-form-encoded renderer will need to do some custom transformations even for simple types as it depends on how things are being rendered by the widget (e.g. ['on', ''] -> [True, False] for checkboxes), I think it's clear we need to consider this as two steps. Perhaps we have a "core" set of data types which are valid return types from a serialization object and all renderers "must" support those types, but we allow renderers to become aware of other data types so they can support them.

Pseudocode:

s = MyNativeTypesSerializer(initial)
data = s.serialize()
json_blob = JSONRenderer().render(data)
html_form = FormRenderer(widgets).render(data)
JSONRenderer().can_render(data)  # True

s = MyRichSerializer
data = s.serialize()
assert isinstance(data['created'], datetime)
JSONRenderer().can_render(data)  # False

JSONRenderer.register_type_encoder(datetime, some_transformation_func)
JSONRenderer().can_render(data)  # True
# OR
JSONRenderer(type_encoders={datetime: some_transformation_func}).can_render(data)  # True

This obviously has some overlap with DjangoJSONEncoder which knows how to handle various data types such as UUID, datetime, lazy strings etc.

Whilst it would be possible, it should be strongly advised that you do not have type encoders for high level types such as instances of models.

Note that it's entirely possible here I'm just rehashing renderers/parsers from DRF, perhaps with some other extensibility ideas and we can pretty much use those for rendering. I think my main change is that perhaps I'd like to see .render(structure, data) or something so that the form renderer is aware of the underlying configuration of the form for example. I probably need to do more research into how DRF handles these layers, and the content negotiation for them.

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