如何在Django Rest Framework中序列化API响应(以JSON格式)以及修改字段并向其中添加字段?

时间:2018-12-20 06:56:55

标签: django serialization django-rest-framework

我从DRF中的不同API获取数据。但是,要实现模块化,我需要对JSON响应进行序列化,并为要调用的每个API端点创建一个“假”模型。

我已经为端点创建了一个模型和一个序列化器,但是在序列化先前的响应时我需要进行另一个API调用,我需要修改一些字段。

    from rest_framework import serializers
    from django.db import models
    from ..nlp_utils.google_nlp import GoogleNLP


    class Search(models.Model):
       title = models.CharField(blank=True, default='')
       link = models.CharField(blank=True, default='')
       snippet = models.CharField(blank=True, default='')
       description = models.CharField(blank=True, default='')
       sentiment_score = models.FloatField(blank=True, default=0.0)
       sentiment_magnitude = models.FloatField(blank=True, default=0.0)


    class SearchResultSerializer(serializers.ModelSerializer):
       class Meta:
          model = Search
          fields = ('title', 'link', 'snippet', 'description','sentiment_score', 'sentiment_magnitude')`

在这里,我需要调用更多的端点并填充sentiment_scoresentiment_magnitude

2 个答案:

答案 0 :(得分:1)

您可以像这样(使用SerializerMethodField)将这些字段直接附加到序列化程序中,而不用在模型中定义它们:

class SearchResultSerializer(serializers.ModelSerializer):
        sentiment_score = serializers.SerializerMethodField()
        sentiment_magnitude = serializers.SerializerMethodField()

       class Meta:
          model = Search
          fields = ('title', 'link', 'snippet', 'description','sentiment_score', 'sentiment_magnitude')

       def get_sentiment_magnitude(self, obj):
            # call external api with search obj which has been stored in your previous call
            return data

       def get_sentiment_score(self, obj):
            # call external api with search obj which has been stored in your previous call
            return data

更新

您可以使用任何Generic ViewsViewset中的上下文来预填充数据。您可以尝试这样:

class YourViewSet(ViewSet):
     ...
     def get_serializer_context(self):
         context = super(YourViewSet, self).get_serializer_context()
         data = get_it_from_api()
         context['sentiment_score'] = data.get('sentiment_score')
         context['sentiment_magnitude'] = data.get('sentiment_magnitude')
         return context

像这样在序列化程序中使用它:

class SearchResultSerializer(serializers.ModelSerializer):
        sentiment_score = serializers.SerializerMethodField()
        sentiment_magnitude = serializers.SerializerMethodField()

       class Meta:
          model = Search
          fields = ('title', 'link', 'snippet', 'description','sentiment_score', 'sentiment_magnitude')

       def get_sentiment_magnitude(self, obj):
            return self.context.get('sentiment_magnitude')

       def get_sentiment_score(self, obj):
            return self.context.get('sentiment_score')

此外,即使不使用通用视图/视图集,您仍然可以传递诸如SearchResultSerializer(instance, context={'sentiment_magnitude': sentiment_magnitude, "sentiment_score": sentiment_score})这样的额外上下文。请参阅documentation

答案 1 :(得分:1)

您有两个选择:

选项1

您可以覆盖序列化器的to_representation方法。每个序列化程序都有一个称为to_representation的方法,该方法将创建将传递给用户的json响应。 例如:

class SearchResultSerializer(serializers.ModelSerializer):

    def to_representation(self, instance):
        r = super(TodoSerializer, self).to_representation(instance)
        r.update({
        'sentiment_score': 'anything you want here'
        })
        return r

选项2

在序列化程序中使用django rest MethodSerializer字段。

class SearchResultSerializer(serializers.ModelSerializer):
    sentiment_magnitude = serializers.SerializerMethodField()

   class Meta:
      model = Search
      fields = '__all__'

   def get_sentiment_magnitude(self, obj):
        sentiment_magnitude = "anything you want here"
        return sentiment_magnitude