gpt4 book ai didi

python - unique_together 不允许更新记录

转载 作者:太空宇宙 更新时间:2023-11-03 17:32:46 24 4
gpt4 key购买 nike

我正在致力于通过 Django Rest Framework 在移动应用 API 中实现 Like/Unlike 功能。

所以我有以下模型:

class PlaylistLikes(models.Model):
user = models.ForeignKey(User)
playlist = models.ForeignKey(Playlist)
like = models.BooleanField(default=0, blank=True)

class Meta:
unique_together = ('user', 'playlist',)
verbose_name = "Playlist like"
verbose_name_plural = "Playlist likes"

我添加了unique_together限制用户喜欢他已经喜欢的播放列表。

我的看法:

class LikesView(viewsets.ModelViewSet):
queryset = PlaylistLikes.objects.all()
serializer_class = LikesSerializer
filter_backends = (filters.OrderingFilter, filters.DjangoFilterBackend, filters.SearchFilter)
filter_class = LikesFilter

search_fields = ('playlist', 'user',)

def create(self, request, *args, **kwargs):
user = request.user
request.data['user'] = user.pk
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
return Response(serializer.data, status=status.HTTP_201_CREATED)

@detail_route(methods=['put'])
def put(self, request, *args, **kwargs):
user = request.user
request.data['user'] = user.pk
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
return Response(serializer.data, status=status.HTTP_200_OK)

和序列化器:

class LikesSerializer(serializers.ModelSerializer):

def create(self, validated_data):
like = PlaylistLikes.objects.create(**validated_data)
playlist = Playlist.objects.get(pk=like.playlist.id)
playlist.likes_count += 1
playlist.save()
return validated_data

def update(self, instance, validated_data):
like = PlaylistLikes.objects.get(**validated_data)
like.like = False
like.save()
playlist = Playlist.objects.get(pk=like.playlist.id)
playlist.likes_count -= 1
playlist.save()
return validated_data

class Meta:
model = PlaylistLikes
fields = ('user', 'playlist', 'like')

网址:

router.register(r'likes', views.LikesView, 'likes')

要喜欢播放列表,我发送 POST方法与主体playlist = 19 , user = 3 , like = 1 。喜欢就创建成功了。为了与相同的播放列表不同,我发送 PUT方法体:playlist = 19 , user = 3 ,但我收到以下错误:

"non_field_errors": [ "The fields user, playlist must make a unique set." ]

我知道发生这种情况是因为 unique_together在模型中。但我没有使用相同的 user 创建新记录和playlist 。我只是想更新现有记录。为什么会出现这种情况以及如何解决这个问题?

最佳答案

发生这种情况是因为在 PUT 方法处理程序中,您创建了一个序列化程序而没有指定实例:

serializer = self.get_serializer(data=request.data)

查看Serializer.__init__():

def __init__(self, instance=None, data=empty, **kwargs):
self.instance = instance
if data is not empty:
self.initial_data = data
self.partial = kwargs.pop('partial', False)
self._context = kwargs.pop('context', {})
kwargs.pop('many', None)
super(BaseSerializer, self).__init__(**kwargs)

您没有提供实例参数,它默认为 None。

对于更新,仅当实例属性不为 None 时,才应跳过 unique_together 验证:

class UniqueTogetherValidator(object):
def exclude_current_instance(self, attrs, queryset):
"""
If an instance is being updated, then do not include
that instance itself as a uniqueness conflict.
"""
if self.instance is not None:
return queryset.exclude(pk=self.instance.pk)
return queryset

要解决这个问题,您可以在初始化序列化器之前移动 Userlikes 对象的查询:

like = PlaylistLikes.objects.get(**query)
serializer = self.get_serializer(like, data=request.data)

关于python - unique_together 不允许更新记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31646452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com