Rishabh Pandey
Rishabh Pandey

Reputation: 219

adding an extra context while passing data to serializer django api

I am trying to add an extra field auth_token in my table with the request.data but it is giving errors. The error is - data['auth_token_id'] = auth_token TypeError: list indices must be integers or slices, not str

My code is given below:

serializers.py

class AppSerializer(serializers.ModelSerializer):

  class Meta:
     model = ThirdPartyApps
     fields = ('app_name', 'package_name', 'auth_token_id')

views.py

@api_view(['POST'])
def add_apps(request):
    data = request.data
    auth_token = request.META.get('HTTP_AUTHTOKEN', '')
    data['auth_token_id'] = auth_token
    serializer = AppSerializer(data=data, many=True)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)
    else:
        return Response(serializer.errors)

I am looking for a way to pass extra data through the serializer. I just want to add auth_token to my model like the request.data but it is giving this error -

data['auth_token_id'] = auth_token TypeError: list indices must be integers or slices, not str

Upvotes: 5

Views: 11196

Answers (3)

sharif_42
sharif_42

Reputation: 571

we can also use class based views like:

class AddApp(APIView):
      def post(request):
        data = request.data
        auth_token = request.META.get('HTTP_AUTHTOKEN', '')
        serializer = AppSerializer(data=data, many=True)
        if serializer.is_valid():
            serializer.save(auth_token_id=auth_token)
            return Response(serializer.data, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors)

also see an awesome tutorial about this topic here

Upvotes: 0

Gabriel Muj
Gabriel Muj

Reputation: 3815

You can send the value also to the serializer's save method

@api_view(['POST'])
def add_apps(request):
    data = request.data
    auth_token = request.META.get('HTTP_AUTHTOKEN', '')
    serializer = AppSerializer(data=data, many=True)
    if serializer.is_valid():
        serializer.save(auth_token_id=auth_token)
        return Response(serializer.data, status=status.HTTP_200_OK)
    else:
        return Response(serializer.errors)

See docs here: http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

Upvotes: 2

monte
monte

Reputation: 555

You should pass it as context like so:

serializers.py

class AppSerializer(serializers.ModelSerializer):
    auth_token_id = serializers.SerializerMethodField()
    def get_auth_token_id(self, obj):
        if "auth_token_id" in self.context:
            return self.context["auth_token_id"]
        return None
    class Meta:
         model = ThirdPartyApps
         fields = ('app_name', 'package_name', 'auth_token_id')

views.py

@api_view(['POST'])
def add_apps(request):
    data = request.data
    auth_token = request.META.get('HTTP_AUTHTOKEN', '')
    serializer = AppSerializer(data=data, many=True, context = {"auth_token_id": auth_token})
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_200_OK)
    else:
        return Response(serializer.errors)

Upvotes: 14

Related Questions