首页 > 解决方案 > 如何从序列化程序内部访问我想验证的实例属性?

问题描述

在我看来,我会做以下事情:

class ReviewViewSet(viewsets.ModelViewSet):

    #queryset, serializer_class and permission_classes defined here

    def perform_create(self, serializer):
        title_id = self.kwargs.get('title_id')
        title = get_object_or_404(Title, pk=title_id)
        serializer.save(author=self.request.user, title=title)

我想验证该评论尚不存在。我正在尝试在序列化程序中执行此操作validate()

class ReviewSerializer(serializers.ModelSerializer):
    title = serializers.SlugRelatedField(slug_field='pk', read_only='True')
    author = serializers.SlugRelatedField(slug_field='username', read_only='True')

    def validate(self, data):
        title = # <-- How to get title here?
        author = self.context['request'].user
        queryset = Review.objects.all().filter(title=title, author=author)
        if queryset.exists():
            raise serializers.ValidationError('Review alredy exists')
        return(data)

    class Meta:
        fields = '__all__'
        model = Review

尝试title = self.title加薪AttributeError: 'ReviewSerializer' object has no attribute 'title'

title在我的情况下如何从内部访问validate()

这是我的Review模型:

class Review(models.Model):
    class Meta:
        ordering = ['-pub_date']
        unique_together = ['title', 'author']

    title = models.ForeignKey(
        Title,
        on_delete=models.CASCADE,
        related_name='reviews',
    )
    author = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE,
        related_name='reviews',
    )
    text = models.TextField('Review text')
    score = models.PositiveSmallIntegerField(
        'Review score',
        validators=[
            MinValueValidator(1),
            MaxValueValidator(10)
        ]
    )
    pub_date = models.DateTimeField(
        'Date and time of review',
        auto_now_add=True,
        db_index=True
    )

标签: pythondjangodjango-rest-framework

解决方案


您的问题的答案在于文档:https ://www.django-rest-framework.org/api-guide/serializers/#object-level-validation

关于validate方法:

此方法采用单个参数,即字段值字典

如果您查看文档中的代码示例,您会发现您可能需要验证的所有数据都在方法的data参数中validate

因此,标题在data['title'].


推荐阅读