我正在应用程序中实现一些投票功能,其中登录用户使用如下这样的有效负载指定他们要投票的帖子:
{
"post": 1,
"value": 1
}
如您所知,user
字段不存在-这是因为它是在我的视图集的perform_create
方法中设置的。我这样做是为了确保投票的user
被设置在服务器端。视图集如下所示:
class CreateVoteView(generics.CreateAPIView):
permission_classes = (permissions.IsAuthenticated,)
serializer_class = VoteSerializer
def perform_create(self, serializer):
serializer.save(user=self.request.user)
这是模型的样子:
class Vote(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='votes', null=False)
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='votes', null=False)
class Values(models.IntegerChoices):
UP = 1, _('Up')
DOWN = -1, _('Down')
value = models.IntegerField(choices=Values.choices, null=False)
class Meta:
unique_together = ('post', 'user')
最后是序列化器:
class VoteSerializer(serializers.ModelSerializer):
class Meta:
model = Vote
fields = ['post', 'value']
据我了解,为了使DRF共同执行唯一的验证,必须将两个字段(在我的情况下为user
和post
)都包括在序列化程序的fields
中。如前所述,我想避免这种情况。还有其他方法可以实现这种验证逻辑吗?
编辑:
为了澄清:记录没有保存-我收到此错误:
django.db.utils.IntegrityError: (1062, "Duplicate entry '1-3' for key 'api_vote.api_vote_post_id_user_id_73614533_uniq'")
但是,我的目标是返回一个Bad Request
而不是一个Internal Server Error
,就像我传统上使用DRF序列化器并从有效载荷中排除必填字段一样。
答案 0 :(得分:0)
要输出由于IntegrityError
而导致的自定义错误消息,可以在序列化程序中覆盖create
方法:
from django.db import IntegrityError
class VoteSerializer(serializers.ModelSerializer):
class Meta:
model = Vote
fields = ['post', 'value']
def create(self, validated_data):
try:
validated_data['user'] = self.context['request'].user
return super().create(validated_data)
except IntegrityError:
error_msg = {'error': 'IntegrityError message'}
raise serializers.ValidationError(error_msg)