在将数据传递给序列化器 django api 时添加额外的上下文

Posted

技术标签:

【中文标题】在将数据传递给序列化器 django api 时添加额外的上下文【英文标题】:adding an extra context while passing data to serializer django api 【发布时间】:2018-03-06 22:29:55 【问题描述】:

我正在尝试使用request.data 在我的表中添加一个额外的字段 auth_token,但它给出了错误。错误是 - data['auth_token_id'] = auth_token TypeError: list indices must be integers or slices, not str

我的代码如下:

序列化器.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)

我正在寻找一种通过序列化程序传递额外数据的方法。 我只想像request.data 一样将auth_token 添加到我的模型中,但它给出了这个错误-

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

【问题讨论】:

【参考方案1】:

你应该像这样将它作为上下文传递:

序列化器.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)

【讨论】:

我将如何保存它? 你的回答绝对准确,但我将如何将山雀保存到我的桌子上 如果您想保存它,您可以创建一个模型(或使用现有模型)并向其中添加一个字段,可能是 models.CharField(max_length = 254) 然后将其设置为 model.auth_token_id = request.META.get('HTTP_AUTHTOKEN', '') 然后 model.save() in您的意见,或者您从哪里收到授权令牌。 但是我的朋友我想将它保存在带有 app_name 和 package_name 的序列化器字段中提到的 auth_token_id 字段中。 啊。正确的。所以你应该得到模型a = ThirdPartyApps.objects.get(. . .) 然后a.auth_token_id = request.META.get('HTTP_AUTHTOKEN', '') 然后a.save() 然后就不需要传递额外的上下文了。【参考方案2】:

您也可以将值发送到序列化程序的保存方法

@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)

在此处查看文档:http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save

【讨论】:

【参考方案3】:

我们还可以使用基于类的视图,例如:

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)

还可以查看有关此主题的精彩教程here

【讨论】:

以上是关于在将数据传递给序列化器 django api 时添加额外的上下文的主要内容,如果未能解决你的问题,请参考以下文章

通过 Redirect 将数据传递给组件

在将数据传递给类构造函数之前,先在Python中预处理数据

如何在将数据推送到导航堆栈之前将数据传递给视图控制器并加载它?

vue js将数据传递给组件

django将数据传递给javascript的最佳方式

在 Flutter 中,如何将数据传递给 Stateless Widget?