简体   繁体   中英

Serializers in django rest framework

Need help with serializer of django rest framework for ManyToMany Field .

Model

class Genre(models.Model):
    genre = models.CharField(max_length=255)

    def __unicode__(self):
        return u'%s' % (self.genre)


class Movie(models.Model):
    popularity = models.FloatField()
    director = models.CharField(max_length=255)
    imdb_score = models.FloatField()
    name = models.CharField(max_length=255)
    genre = models.ManyToManyField(Genre)

    def __unicode__(self):
        return u'%s' % (self.name)

Serializer

class MovieSerializer(serializers.ModelSerializer):
    class Meta:
        model = Movie
        fields = ('popularity', 'director', 'genre', 'imdb_score', 'name')
        depth = 1

View

class MovieList(APIView):

    def get(self, request, format=None):
         movies = Movie.objects.all()
         serializer = MovieSerializer(movies, many=True)
             return Response(serializer.data)

The result of the API using the above serializer is below,

{
    "popularity":83.0,
    "director":"Victor Fleming",
    "genre":[
    {"id":1,"genre":"Adventure"},
    {"id":2,"genre":"Family"},
    {"id":3,"genre":"Fantasy"},
    {"id":4,"genre":"Musical"}
    ],
    "imdb_score":8.3,
    "name":"The Wizard of Oz"
}

How can I exclude id and genre so that the output is like shown below.

{
    "99popularity": 83.0,
    "director": "Victor Fleming",
    "genre": [
      "Adventure",
      " Family",
      " Fantasy",
      " Musical"
    ],
    "imdb_score": 8.3,
    "name": "The Wizard of Oz"
  }

What you will most likely want to do is use a StringRelatedField for the genre field on your MovieSerializer. For instance:

class MovieSerializer(serializers.ModelSerializer):
    genre = serializers.StringRelatedField(many=True)

    class Meta:
        model = Movie
        fields = ('popularity', 'director', 'genre', 'imdb_score', 'name')
        depth = 1

Nested serializing is the most effective way to handle this problem. The issue with "StringRelatedField" is it's read-only and it will raise "StringRelatedField.to_internal_value() must be implemented" error during post/update. Take a look to the update that I made on your code:

Genre Serializer

class GenreSerializer(serializers.ModelSerializer):
      class Meta:
           model = Genre
           fields = ('genre')

Movie serializer

class MovieSerializer(serializers.ModelSerializer):
      genre = GenreSerializer(many=True)

      class Meta:
            model = Movie
            fields = ('popularity', 'director', 'genre', 'imdb_score', 
            'name')
            depth = 1

      #Method to manage create/post requests 
      def create(self, validated_data):
          genre_data = validated_data.pop('genre')
          movie = MoviewModel.objects.create(**validated_data)

          for genre_data in genre_data:
              GenreModel.objects.create(movie=movie, **genre_data)
          return movie

Navigate to DRF documentation for more:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM