简体   繁体   English

在唯一模型字段上的DRF PUT请求

[英]DRF PUT request on unique model field

I have the following model: 我有以下模型:

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)

and serializer: 和序列化器:

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

When I try to send a put request without changing name field from Movie model it throws an error 当我尝试发送放置请求而不更改Movie模型的name字段时,它将引发错误

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

However, I can perfectly update any other field if I change the name field's value each time. 但是,如果每次更改name字段的值,我都可以完美地更新任何其他字段。

The problem is in Movie model defined by you. 问题出在您定义的电影模型中。 When you set the name field of Movie model as unique = True ,then any new entry with same movie name will always throw an error. 当将“电影”模型的名称字段设置为unique = True时 ,具有相同电影名称的任何新条目将始终引发错误。

In your model, 在您的模型中

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)

If you want to add two entries with the same name,remove the line unique = True or make sure to save every entry with a different name. 如果要添加两个具有相同名称的条目,请删除行unique = True或确保以不同的名称保存每个条目。

Or,if you want to update the record/entry then you don't need to assign a value for name field,just remove that line from your code,alternatively check if the name of the movie is already same with an improvement in the code like this : 或者,如果您要更新记录/条目,则无需为名称字段分配值,只需从代码中删除该行,或者检查电影名称是否已经相同,并且代码有所改进像这样 :

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

Hope this helps,Thanks. 希望这会有所帮助,谢谢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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