django rest框架如何用一个请求为多个表添加条目?

时间:2017-09-10 13:31:18

标签: python django django-rest-framework

我正在尝试在向电影模型添加电影的同时为流派模型添加流派,但是当我尝试添加尚未存在的流派条目时,我得到以下响应对象(工作正常如果它已存在于表中):

{'genres': ['Object with genre=Mystery does not exist.']}

我认为它应该可以在MovieSerializer的create()方法中使用object.get_or_create(),但它似乎不起作用。

此外,我通过POST请求以以下格式发送数据:

{'tmdb_id': 14,
'title': 'some movie',
'release_date': '2011-12-12',
'genres': ['Action', 'Mystery']}

不确定这是否重要。

以下是代码:

Views.py

class CreateMovieView(generics.ListCreateAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

    def perform_create(self, serializer):
        """Save the post data when creating a new movie."""
        serializer.save()


class MovieDetailsView(generics.RetrieveUpdateDestroyAPIView):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

Models.py

class Genre(models.Model):

    genre = models.CharField(max_length=65)

    def __str__(self):
        return "{}".format(self.genre)


class Movie(models.Model):

    tmdb_id = models.IntegerField(primary_key=True)
    title = models.CharField(max_length=255)
    release_date = models.DateField()
    imdb_id = models.CharField(max_length=255, blank=True)
    img_path = models.CharField(max_length=255, blank=True)
    runtime = models.CharField(max_length=65, blank=True)
    synopsis = models.TextField(blank=True)
    imdb_rating = models.DecimalField(max_digits=3, decimal_places=1, blank=True, null=True)
    metascore = models.IntegerField(blank=True, null=True)

    genres = models.ManyToManyField(Genre, related_name='genres', blank=True)

    def __str__(self):
        return "{}".format(self.title)

serializers.py

class MovieSerializer(serializers.ModelSerializer):
    """Serializer to map the Model instance into JSON format."""

    genres = serializers.SlugRelatedField(slug_field='genre', many=True, queryset=Genre.objects.all())

    class Meta:
        """Meta class to map serializer's fields with the model fields."""
        model = Movie
        fields = ('tmdb_id',
                  'imdb_id',
                  'title',
                  'release_date',
                  'img_path',
                  'runtime',
                  'synopsis',
                  'imdb_rating',
                  'metascore',
                  'genres')

def create(self, validated_data):
    genres_data = validated_data.pop('genres')
    movie = Movie.objects.create(**validated_data)

    for genre_name in genres_data:
        genre, created = Genre.objects.get_or_create(genre=genre_name)
        movie.genres.add(genre)

    return movie

1 个答案:

答案 0 :(得分:0)

我不确定为什么这是你得到的错误,但似乎你没有正确使用视图来允许创建Movie实例。 ListCreateAPIView可让您创建电影列表 相反,您应该将CreateModelMixin添加到其他视图中:

class MovieDetailsView(generics.RetrieveUpdateDestroyAPIView,
                       mixins.CreateModelMixin):
    queryset = Movie.objects.all()
    serializer_class = MovieSerializer

或者更好的是,使用ModelViewSet:

from restframework import viewsets

class MovieViewSet(viewsets.ModelViewSet):
    queryset = ...