Как сериализовать ответ API (в JSON), изменить и добавить к нему поля в Django Rest Framework? - PullRequest
0 голосов
/ 20 декабря 2018

Я получаю данные из разных API в DRF.Однако для обеспечения модульности мне нужно сериализовать ответ 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_score и sentiment_magnitude

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

У вас есть две опции:

Опция 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
0 голосов
/ 20 декабря 2018

Вместо того, чтобы определять его в модели, вы можете напрямую прикрепить эти поля в сериализаторе следующим образом (используя 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

Обновление

Выможно использовать контекст из любого универсальных представлений или представлений для предварительного заполнения данных.Вы можете попробовать так:

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

Кроме того, даже без использования универсальных представлений / viewset вы все равно можете передать дополнительный контекст, например:это SearchResultSerializer(instance, context={'sentiment_magnitude': sentiment_magnitude, "sentiment_score": sentiment_score}).Пожалуйста см. документацию .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...