2016-11-17 175 views
0

我有以下型号:DRF PUT请求

class Movie(models.Model): 
    name = models.CharField(max_length=800, unique=True) 
    imdb_rating = models.IntegerField(null=True) 
    movie_choice = (
     ('Act', 'Action'), 
     ........... 
    ) 
    movie_type = models.CharField(max_length=3, choices=movie_choice) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 


class Hiren(models.Model): 
    movie = models.ForeignKey(Movie) 
    watched_full = models.BooleanField(default=True) 
    rating = models.IntegerField() 
    source = models.CharField(max_length=500, null=True) 
    watched_at = models.DateField() 
    quality_choice = (
    .................. 
    ) 
    video_quality = models.CharField(max_length=3, choices=quality_choice) 
    created_at = models.DateField(auto_now_add=True) 
    updated_at = models.DateField(auto_now=True) 

和串行:

class MovieSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Movie 
     fields = '__all__' 


class HirenSerializer(serializers.ModelSerializer): 
    movie = MovieSerializer() 

    class Meta: 
     model = Hiren 
     fields = ('movie', 'id', 'watched_full', 'rating', 'source', 'video_quality', 'watched_at') 

    def update(self, instance, validated_data): 
     instance.movie.name = validated_data.get('movie', {}).get('name') 
     instance.movie.imdb_rating = validated_data.get('movie', {}).get('imdb_rating') 
     instance.movie.movie_type = validated_data.get('movie', {}).get('movie_type') 
     instance.watched_full = validated_data.get('watched_full', instance.watched_full) 
     instance.rating = validated_data.get('rating', instance.rating) 
     instance.source = validated_data.get('source', instance.source) 
     instance.video_quality = validated_data.get('video_quality', instance.video_quality) 
     instance.watched_at = validated_data.get('watched_at', instance.watched_at) 
     instance.movie.save() 
     instance.save() 

     return instance 

当我试图发送一个PUT请求,而不从电影模式转变name领域,它抛出一个错误

{ 
    "movie": { 
     "name": [ 
      "movie with this name already exists." 
     ] 
    } 
} 

但是,我可以完美更新任何其他领域,如果我改变name每次的字段值。

+0

请将partial_update = True置于序列化程序中,然后将请求工作正常 –

回答

1

问题出在您定义的电影模型中。 当您将电影模型的名称字段设置为unique = True时,任何具有相同电影名称的新条目将始终引发错误。

在模型中,

class Movie(models.Model): 
    name = models.CharField(max_length=800, unique=True) 
    imdb_rating = models.IntegerField(null=True) 
    movie_choice = (
     ('Act', 'Action'), 
     ........... 
    ) 
    movie_type = models.CharField(max_length=3, choices=movie_choice) 
    created_at = models.DateTimeField(auto_now_add=True) 
    updated_at = models.DateTimeField(auto_now=True) 

如果你想添加两个条目具有相同的名称,删除行唯一= True或请务必保存具有不同名称的每个条目。

或者,如果您想更新记录/条目,则不需要为名称字段分配值,只需从代码中删除该行,或者检查电影的名称是否与这样的代码的改进:

class HirenSerializer(serializers.ModelSerializer): 
    movie = MovieSerializer() 

    class Meta: 
     model = Hiren 
     fields = ('movie', 'id', 'watched_full', 'rating', 'source', 'video_quality', 'watched_at') 

    def update(self, instance, validated_data): 
     movie_name = validated_data.get('movie', {}).get('name') 

     if movie_name != instance.movie.name : 
      instance.movie.name = movie_name 

     instance.movie.imdb_rating = validated_data.get('movie', {}).get('imdb_rating') 
     instance.movie.movie_type = validated_data.get('movie', {}).get('movie_type') 
     instance.watched_full = validated_data.get('watched_full', instance.watched_full) 
     instance.rating = validated_data.get('rating', instance.rating) 
     instance.source = validated_data.get('source', instance.source) 
     instance.video_quality = validated_data.get('video_quality', instance.video_quality) 
     instance.watched_at = validated_data.get('watched_at', instance.watched_at) 
     instance.save() 

     return instance 

希望这可以帮助,谢谢。

+0

我遵循了您的上一个建议。我仍然有同样的错误。我发现这一点,如果我不改变'name'值,更新方法就无法执行。它只是抛出第一个错误。 – pyprism

+0

@pyprism你的代码的一行是不必要的,要么** instance.movi​​e.save()**或** instance.save()**。尝试删除他们alternate.Then我的第二个代码将工作。 –

+0

@pyprism我很确定** instance.movi​​e.save()**行是不必要的。你应该删除这一行,然后代码将工作。 –