Django REST Framework自定义图片URL验证器返回格式不符问题
Django REST Framework自定义验证器错误返回格式不符问题
我正在开发一个Django REST Framework项目,其中ProjectModel包含image_file(本地上传图片)和image_url(外部托管图片)字段,同时为image_url实现了ImageURLValidator自定义验证器,用于校验URL是否以http:///https://开头、格式合法且指向图片。但运行单元测试时发现,验证返回的错误信息格式与预期不符:实际返回包含ErrorDetail的结构,而预期为纯字符串列表。
相关代码文件
models.py
from django.db import models class ProjectModel(models.Model): image_file = models.ImageField( null=True, blank=True, upload_to='project/%Y/%m/%d' ) image_url = models.URLField( null=True, blank=True )
serializers.py
from rest_framework import serializers from .validators import ImageURLValidator from .models import ProjectModel class ProjectSerializer(serializers.ModelSerializer): image_url = serializers.URLField( required=False, allow_null=True, allow_blank=True, validators=[ImageURLValidator()] ) class Meta: model = ProjectModel fields = ['id', 'image_file', 'image_url']
validators.py
import requests from rest_framework import serializers from django.core import validators from django.utils.translation import gettext_lazy as _ class ImageURLValidator: def __call__(self, value): if not value.startswith(('http://', 'https://')): raise serializers.ValidationError( _("URL must start with 'http://' or 'https://'") ) try: validators.URLValidator()(value) except serializers.ValidationError: raise serializers.ValidationError( _("Invalid URL format") ) # 获取URL内容并检查图片格式 response = None try: response = requests.get(value) response.raise_for_status() # 检查请求状态码 except requests.exceptions.RequestException as e: raise serializers.ValidationError( _("Error fetching content from URL: %(error)s") % {'error': str(e)} ) content_type = response.headers['content-type'] if not content_type.startswith(('image/')): raise serializers.ValidationError( _("URL must point to an image") )
错误返回对比
实际返回结果
{'image_url': [ErrorDetail(string="URL must start with 'http://' or 'https://'", code='invalid')]}
预期返回结果
{'image_url': ["URL must start with 'http://' or 'https://'"]}
单元测试代码
class TestFail(TestBase): def test_file_url_starts_with_http_or_https(self): # 移除http://或https://前缀 image_url = self.faker.image_url(width=640, height=480) pattern = re.compile(r'https?://') image_url = pattern.sub('', image_url) post_data = { 'image_url': image_url, } url_name = "create-project" url = f"{APP_LABEL}:{url_name}" end_point = reverse(url) response = self.client.post( end_point, post_data, # format="multipart" ) expected = status.HTTP_400_BAD_REQUEST actual = response.status_code self.assertEqual(expected, actual) msg = _("URL must start with 'http://' or 'https://'") expected = {'image_url': [msg]} actual = response.data self.assertDictEqual(expected, actual)
内容的提问来源于stack exchange,提问作者erhan
相关产品推荐
相关产品推荐

