Django REST Framework: Changing keys during deserialization

Viewed 41

I'm writing a little app in Django using the Django rest framework. The goal is pretty simple: I want to be able to get a request per HTTP POST method with a JSON object attached to it. In the end, I want to return the same JSON object but with different key values. To be precise I want to translate the key values from german to English.

So this is what I would get: { "vorname": "John", "nachname": "Doe" }

And this is what I want to return: { "firstname": "John", "lastname": "Doe" }

I'm trying to do this using a serializer, and it works already, just not how I would like it to work.

This is the model I'm using:

class Name(models.Model):
    firstname = models.CharField(max_length=255)
    lastname = models.CharField(max_length=255)

And this is the serializer:

class NameSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Name
        fields = ['firstname', 'lastname']

And of course, there is also a view:

@api_view(['POST'])
@parser_classes([JSONParser])
def convert(request):
    request.data['firstname'] = request.data.pop('Vorname')
    request.data['lastname'] = request.data.pop('Nachname')
    serializer = NameSerializer(data=request.data)

    if serializer.is_valid():
        print(serializer.data)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)  
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

So as I said this already works with using dict.pop() to transform the request.data dictionary. But what I would want it to do is to manage the mapping inside the serializer if possible so that there isn't any extra code needed in the view. After searching for hours my head is just dizzy now and I have no idea if this is even possible.

So the question would be: How do I map the german keys onto my English keys using only the serializer?

1 Answers

So I found an answer to this for anyone else searching. It's not perfect and I feel like there is a better way to do this. If you have a better idea, please feel free to post it here =)

I simly wrote an override of the __init__ function inside my serializer so that it looks like this now:

class NameSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Name
        fields = ['firstname', 'lastname']

    def __init__(self, instance=None, data=empty, **kwargs):
        super().__init__(instance, data, **kwargs)
        self.initial_data['firstname'] = self.initial_data.pop('Vorname')
        self.initial_data['lastname'] = self.initial_data.pop('Nachname')

So I basicly moved the solution I had before to the serializer. It doesn't feel clean but it works!

Related