Django-Rest: how to access data if JSON or URL-encoded inside view?

I need to access some nested information inside request.data inside a post definition. The data sent is in the following form:

{
    ...
    "licence": {
        "tenant_name": "tenant1",
        ...
    }
}

Since I'm using Django Rest with the default parsers installed (JSONParser and FormParser) I could receive JSON or HTML form content inside the request. I'd like to keep both and don't change the default parser_classes of the view. The request.data has different types and representations based on the content:

  • HTML-encoded: <QueryDict: {..., 'licence.tenant_name': ['tenant1']}>
  • JSON: {..., 'licence': {'tenant_name': 'tenant1'}}

To handle this I currently check on the type. Is there a better way as a general use case?

class SubscribeView(views.APIView):
    serializer_class = SubscriptionSerializer
    permission_classes = (AllowAny, )

    def post(self, request):
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)

        tenant_name = request.data['licence']['tenant_name'] if type(request.data) is dict else request.data['licence.tenant_name']
        # perform actions on tenant_name

        serializer.save()

        status_code = status.HTTP_201_CREATED
        response = {
            'success': True,
            'status_code': status_code,
            'message': 'New subscription successfully created',
            'subscription': serializer.data
        }
        return Response(response, status=status_code)

I didn't catch that I can just use the serializer itself! It has built in features to handle multiple data encodings.

So I can just transform this:

tenant_name = request.data['licence']['tenant_name'] if type(request.data) is dict else request.data['licence.tenant_name']

To this:

tenant_name = serializer.validated_data.get('licence', {}).get('tenant_name', '')
Back to Top