验证 REST 端点上的字段

Posted

技术标签:

【中文标题】验证 REST 端点上的字段【英文标题】:Validating fields on REST endpoint 【发布时间】:2019-06-27 21:03:06 【问题描述】:

我有一个端点,当被调用时应该更新或创建用户的配置文件。在此端点内有 3 个字段需要创建或更新 (avatar, bio, gender) 目前,我正在使用 UpdateAPIView,如下所示:

class UpdateOrCreateProfile(UpdateAPIView):
    serializer_class = ProfileSerializer

    def get_object(self):
        return Profile.objects.get(user=self.request.user) 

序列化程序类如下所示:

class ProfileSerializer(serializers.ModelSerializer):
    class Meta:
        model = Profile
        fields = '__all__'

这很好用,但是验证无法正常工作。显示的表单有一个 clean_avatar 函数,它不接受 200x200 像素以下的图像。像这样:

class ProfileForm(ModelForm):
    avatar = forms.ImageField(required=False, widget=forms.FileInput)
    bio = forms.CharField(widget=forms.Textarea(attrs='rows': 3, "placeholder": "Bio"), max_length=200,
                          required=False)
    class Meta:
        model = Profile
        fields = ['avatar', 'bio', 'gender']

    def clean_avatar(self):
        picture = self.cleaned_data.get("avatar")
        if picture:
            w, h = get_image_dimensions(picture)
            if w < 200:
                raise forms.ValidationError("The image is %i pixel wide. It's supposed to be more than 200px" % w)
            if h < 200:
                raise forms.ValidationError("The image is %i pixel high. It's supposed to be 200px" % h)
        return picture

我怎样才能使表单上发生的相同验证也发生在我的端点中?

【问题讨论】:

我想你想要这个DRF Custom validator 你应该在你的 ImageField 中传递你的验证器 Ref @KhashayarGhamati 非常有趣,谢谢! 我想你要找的是field level validation in serializer 【参考方案1】:

您可以编写一个 validate_avtar 方法。它作为表单清理方法工作。

class ProfileSerializer(serializers.ModelSerializer):
   class Meta:
      model = Profile
      fields = '__all__'

   def validate_avatar(self, picture):
     if picture:
        w, h = get_image_dimensions(picture)
        if w < 200:
            raise serializers.ValidationError("The image is %i pixel wide. It's supposed to be more than 200px" % w)
        if h < 200:
            raise serializers.ValidationError("The image is %i pixel high. It's supposed to be 200px" % h)
     return picture

【讨论】:

以上是关于验证 REST 端点上的字段的主要内容,如果未能解决你的问题,请参考以下文章

将 Spring REST 端点配置为在序列化响应对象中的日期字段时忽略附加时区

使用ARBCreateSubscriptionRequest验证信用卡或借记卡,例如客户资料的validationMode字段

多个字段解析器使用不同的查询参数解析相同的 REST API

Django rest framework 之 DictField、ListField、自定义字段

Django REST Framework 自定义字段验证

将可编辑字段作为 Django-Rest-Framework Serializer 的验证数据方法传递