扩展表单字段以添加新验证
我写了一个应用程序,它使用表单来收集信息,然后通过电子邮件发送这些信息。很多表单都有一个文件字段,用来附加文件到电子邮件中。我想验证两件事:一个是文件的大小(以确保我们的邮件服务器能接受这些邮件),另一个是检查文件的扩展名,以避免用户附加一些他们无法使用的文件类型。
(这是我想要扩展的Python类)
class FileField(Field):
widget = FileInput
default_error_messages = {
'invalid': _(u"No file was submitted. Check the encoding type on the form."),
'missing': _(u"No file was submitted."),
'empty': _(u"The submitted file is empty."),
'max_length': _(u'Ensure this filename has at most %(max)d characters (it has %(length)d).'),
}
def __init__(self, *args, **kwargs):
self.max_length = kwargs.pop('max_length', None)
super(FileField, self).__init__(*args, **kwargs)
def clean(self, data, initial=None):
super(FileField, self).clean(initial or data)
if not self.required and data in EMPTY_VALUES:
return None
elif not data and initial:
return initial
# UploadedFile objects should have name and size attributes.
try:
file_name = data.name
file_size = data.size
except AttributeError:
raise ValidationError(self.error_messages['invalid'])
if self.max_length is not None and len(file_name) > self.max_length:
error_values = {'max': self.max_length, 'length': len(file_name)}
raise ValidationError(self.error_messages['max_length'] % error_values)
if not file_name:
raise ValidationError(self.error_messages['invalid'])
if not file_size:
raise ValidationError(self.error_messages['empty'])
return data
3 个回答
0
这是我最后做的事情:
在我应用的设置文件里:
exts = ['doc', 'docx', 'pdf', 'jpg', 'png', 'xls', 'xlsx', '.xlsm', '.xlsb']
max_email_attach_size = 10485760 #10MB written in bytes
在一个我叫做 formfunctions 的新文件里:
from django import forms
from django.forms.util import ErrorList, ValidationError
from app.settings import exts, max_email_attach_size
class SizedFileField(forms.FileField):
def clean(self, data, initial=None):
if not data in (None, ''):
try:
if data.size > max_email_attach_size:
raise ValidationError("The file is too big")
file_extension = data.name.split('.')[1]
if file_extension not in exts:
raise ValidationError("Invalid File Type")
except AttributeError:
raise ValidationError(self.error_messages['invalid'])
return forms.FileField.clean(self, data, initial)
还有在我的表单文件里:
from formfunctions import SizedFileField
这是表单文件中的一个示例类:
class ExampleClass(forms.Form):
Email_Body = forms.CharField(widget=forms.Textarea, required=False)
Todays_Date = forms.CharField()
Attachment = SizedFileField(required=False)
1
我觉得直接继承实际的字段类太麻烦了。其实更简单的方法是扩展你的表单类。你可以添加一个方法来“清理”文件字段。
比如说:
class MyForm(forms.Form):
attachment = forms.FileField(...)
def clean_attachment(self):
data = self.cleaned_data['attachment'] // UploadedFile object
exts = ['jpg', 'png'] // allowed extensions
// 1. check file size
if data.size > x:
raise forms.ValidationError("file to big")
// 2. check file extension
file_extension = data.name.split('.')[1] // simple method
if file_extension not in exts:
raise forms.ValidationError("Wrong file type")
return data
这只是一个基本的例子,还有一些不完善的地方。不过你可以用这个例子,慢慢改进,直到你有一个适合自己的版本。
推荐阅读:
2
只需要重写一下“clean”这个方法就可以了:
def clean(self, data, initial=None):
try:
if data.size > somesize:
raise ValidationError('File is too big')
(junk, ext) = os.path.splitext(data.name)
if not ext in ('.jpg', '.gif', '.png'):
raise ValidationError('Invalid file type')
except AttributeError:
raise ValidationError(self.error_messages['invalid'])
return FileField.clean(self, data, initial)