我正在尝试为Django ModelForm添加一些验证,但我正在以某种方式破坏保存。我有一个带有FileField的模型,我希望FileField只接受PDF。
我写了一个验证函数:
def validate_pdf(value):
if not value.name.endswith('pdf'):
raise ValidationError(u'Invalid File')
我将它附加到我的模型的FileField:
class MediaObject(models.Model):
...
pdf = models.FileField(upload_to='pdfs', blank=True, validators=[validate_pdf])
然后,当我使用我之前使用的功能型ModelForm时,我能够选择一个文件,但该文件未在提交时上传或保存到模型中。它表现得好像我根本没有选择任何文件。如果我没有选择文件,表单的其余部分工作正常。如果我确实选择了一个文件,那么除了保存文件之外,其他表单也无法保存。
我删除了验证器并且表单恢复正常工作,但显然没有我想要的验证器。我尝试转到表单并覆盖每个字段的clean方法,并且表单的整体清理,但结果每次都相同 - 使用附加了验证器的任何字段都会破坏保存。
我是否遗漏了将验证器附加到文件字段的内容?
(旁白:我知道查看文件扩展名是一种验证文件类型的愚蠢方法。我打算扩展验证器以查看mimetype,但正如他们所说,在你运行之前走路。)
在某些视图处理中编辑以帮助诊断问题:
@user_passes_test(p_restricted)
def pDashCTSCBook(request, *args, **kwargs):
user = request.user
mo = MediaObject.objects.get(id=request.GET.get('id'))
if request.method == 'POST':
form = pCTSCForm(request.POST, request.FILES, instance=mo)
if form.is_valid():
tsc = form.save()
form.save_m2m()
return HttpResponseRedirect('/successpage/')
else:
form = pCTSCForm(instance=mo)
return render_to_response('dir/template.html', {'mo': mo, 'user': user, 'form': form}, context_instance=RequestContext(request))
经过更多的讨论,我可以自信地说,问题是ValidationError永远不会被引发。调用第一个form.is_valid()
,检查验证器,如果测试失败,则出现问题 - 而不是停止并引发错误,它会一直尝试保存无效表单。如果验证器通过但是一切正常。我尝试从django.forms和django.core.exceptions获取ValidationError
,结果相同。
如果我进入验证器并将其更改为以下内容:
def validate_pdf(value):
if not value.name.endswith('pdf'):
return ValidationError(u'Invalid File') #note return rather than raise
return value
只要我尝试上传PDF,一切正常。但是,如果我尝试上传其他内容,我会收到AttributeError: ValidationError object has no attribute '_committed'
当表单命中form.save()
时会引发此AttributeError,这告诉我即使验证程序正在执行其工作并且正在执行if not value.name.endswith('pdf')
下面的代码,但错误未被引发。< / p>
答案 0 :(得分:0)
尝试使用此功能(可能验证器在考虑字段有效之前需要一些返回值):
def validate_pdf(value):
if not value.name.endswith('pdf'):
raise ValidationError(u'Invalid File')
return