以下是一个解决方案,它作为一个简单的模型字段工作,您可以将其放在 models.ImageField
的位置上:
class Icon(models.Model):
image_file = SVGAndImageField()
您需要在代码中定义以下类和函数:
from django.db import models
class SVGAndImageField(models.ImageField):
def formfield(self, **kwargs):
defaults = {'form_class': SVGAndImageFieldForm}
defaults.update(kwargs)
return super().formfield(**defaults)
这是 SVGAndImageFieldForm
的样子:
from django import forms
from django.core.exceptions import ValidationError
class SVGAndImageFieldForm(forms.ImageField):
def to_python(self, data):
try:
f = super().to_python(data)
except ValidationError:
return validate_svg(data)
return f
我从其他解决方案中获取了validate_svg
函数:
import xml.etree.cElementTree as et
def validate_svg(f):
f.seek(0)
tag = None
try:
for event, el in et.iterparse(f, ('start',)):
tag = el.tag
break
except et.ParseError:
pass
if tag != '{http://www.w3.org/2000/svg}svg':
raise ValidationError('Uploaded file is not an image or SVG file.')
f.seek(0)
return f
如果你希望只使用 SVG 文件 模型字段 - 你可以更加简单地完成它。
只需创建一个继承自 models.FileField
的类,在 __init__
方法中,您可以将 validate_svg
函数添加到 kwargs['validators']
中。
或者只是将此验证器添加到 models.FileField
中,并快乐 :)
svg
有多容易可能是有好处的。例如,billion laughs 如果您使用xml.etree
(如此处许多答案所建议)将会使您的服务器崩溃。 - djvg