You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么Django REST Framework序列化器的validate_width校验不生效

问题原因分析
  • DRF 的 validate_<字段名> 字段级校验规则,仅会对序列化器显式声明/包含的字段生效。你的ImageUploadSerializer的Meta.fields中只声明了['id', 'url', 'picture']三个字段,width 并没有被纳入序列化器的校验字段范围,即便你在构造序列化器时传入了width参数,序列化器也会直接忽略该字段,不会触发对应的validate_width校验逻辑。
  • 你在视图中虽然定义了专门用于接收参数的ImageResizeSerializer,但完全没有调用它做请求参数校验,直接从request.data中取了width和height,相当于这个序列化器的定义完全没有生效。
  • 即便后续你让validate_width生效,当前create方法中也会直接读取图片本身的宽高覆盖你传入的width参数,校验逻辑的结果也不会影响最终落库的数据。
修复方案
  1. 调整ImageUploadSerializer的字段配置,把width、height纳入校验范围:
class ImageUploadSerializer(serializers.ModelSerializer): 
    picture = Base64ImageField()
    # 显式声明width、height字段,若模型中已存在对应字段,也可以直接加到下方fields列表中
    width = serializers.IntegerField()
    height = serializers.IntegerField()

    class Meta:
        model = ImageUpload
        # 补充width、height到字段列表
        fields = ['id', 'url', 'picture', 'width', 'height']

    def validate_width(self, value):
        if value < 100:
            raise serializers.ValidationError('Width shouldn\'t be less then 100')
        return value

    def create(self, validated_data):
        im = Image.open(validated_data['picture'])
        # 如果需要校验用户传入的width,就不要用图片本身的width覆盖传入参数
        # 如果你实际需要校验的是图片本身的宽度,就不需要传width参数,直接在校验逻辑中读取图片尺寸判断即可
        # validated_data['width'] = im.size[0]
        # validated_data['height'] = im.size[1]
        validated_data['name'] = f'{datetime.datetime.now()}'
        return super().create(validated_data)
  1. 调整视图逻辑,先调用ImageResizeSerializer校验请求参数,再走后续逻辑:
class ResizeImageView(APIView):
    serializer_class = ImageResizeSerializer

    def post(self, request, *args, **kwargs):
        # 先校验请求参数
        param_serializer = self.serializer_class(data=request.data)
        param_serializer.is_valid(raise_exception=True)
        width = param_serializer.validated_data['width']
        height = param_serializer.validated_data['height']
        
        with open('c:/Users/KK/Desktop/tiny-kitten-in-sunlight.jpg', 'rb') as img:
            mock_resized_obj = img.read()
            mock_resized_obj_64 = pybase64.b64encode_as_string(mock_resized_obj)

        serializer = ImageUploadSerializer(
                    data={'picture': mock_resized_obj_64,
                          'width': width, 
                          'height': height}
        )

        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

内容的提问来源于stack exchange,提问作者Vlad Vlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 06:45:01