python-3.xdjangoserializationdjango-rest-frameworkdjango-serializer

Different name of serializer data django


I want to serializer a list of dicts that contain a whitespace.
Obviously I can't write cat name = serializer.Charfield(...) in Python
(see the space between the and cat).

So, I tried source=, but I get an error.

{ "cat_name": [ "This field is required." ] }

Here's my code:

class MySerializer(serializers.Serializer):
    cat_name = serializers.CharField(source='Cat name')

s = MySerializer(data={'Cat name': 'Smith'})
s.is_valid(raise_exception=True)

What am I doing wrong?


Note that this can't change:

data={'Cat name': 'Smith'}

Solution

  • You can make a mixin that translates keys to values, like:

    class TranslateMixin:
        translation = {}
        _reverse_translation = None
    
        @property
        def reverse_translation(self):
            if self._reverse_translation is None:
                type(self)._reverse_translation = {
                    v: k for k, v in self.translation.items()
                }
            return self._reverse_translation
    
        def to_internal_value(self, data):
            super().to_internal_value(
                {self.translation.get(k, k): v for k, v in data.items()}
            )
    
        def to_representation(self, instance):
            result = super().to_representation(instance)
            return {self.reverse_translation.get(k, k): v for k, v in result.items()}

    and then define a translation with:

    class MySerializer(TranslateMixin, serializers.Serializer):
        cat_name = serializers.CharField()
        translation = {'Cat name': 'cat_name'}

    This will thus pre-process the items when you use the serializer to generate instances, and post-process in reverse when you serialize instances.

    I would however advise not to use spaces in field names, not at the JavaScript side either. Since fields with spaces can not act as identifiers, it makes code a lot more complicated.