Django表单验证,clean()和文件上传

时间:2011-02-17 23:15:25

标签: django validation upload

有人能够确切地说明上传文件实际写入FileField中“upload_to”返回的位置的时间,特别是有关字段,型号,表单验证和清洁的顺序吗?

现在我在我的模型上有一个“干净”的方法,它假定上传的文件就位,所以它可以对它进行一些验证。看起来该文件尚未保存,可能只是保存在临时位置或内存中。如果是这种情况,如果我需要执行一些外部进程/程序来验证文件,如何“打开”它或找到它的路径?

谢谢,

伊恩

3 个答案:

答案 0 :(得分:8)

表单清理与实际保存文件或保存任何其他数据无关。在运行模型实例的save()方法之前,不会保存文件(请注意,如果使用ModelName.objects.create(),则会自动调用此save()方法)。

绑定表单将包含一个打开的File对象,因此您应该能够直接对该对象进行任何验证。例如:

form = MyForm(request.POST, request.FILES)
if form.is_valid():
    file_object = form.cleaned_data['myFile']
    #run any validation on the file_object, or define a clean_myFile() method 
    #  that will be run automatically when you call form.is_valid()

    model_inst = MyModel('my_file' = file_object,
                     #assign other attributes here....
                     )
    model_inst.save() #file is saved to disk here

答案 1 :(得分:3)

你需要做什么?如果您的验证在没有临时文件的情况下有效,您可以通过调用文件字段返回的read()来访问数据。

def clean_field(self):
    _file = self.cleaned_data.get('filefield')
    contents = _file.read()

如果你确实需要它在磁盘上,你知道从哪里开始:)把它写到一个临时位置并做一些魔术吧!

答案 2 :(得分:1)

或将其写为自定义表单字段。这是我如何使用'mutagen'库验证MP3文件的基本思路。

注意:

  • 首先检查文件大小,然后如果正确的大小写入tmp位置。
  • 将文件写入SETTINGS中指定的临时位置,检查其MP3,然后将其删除。

代码:

from django import forms

import os
from mutagen.mp3 import MP3, HeaderNotFoundError, InvalidMPEGHeader

from django.conf import settings

class MP3FileField(forms.FileField):

    def clean(self, *args, **kwargs):
        super(MP3FileField, self).clean(*args, **kwargs)
        tmp_file = args[0]

        if tmp_file.size > 6600000:
            raise forms.ValidationError("File is too large.")

        file_path = getattr(settings,'FILE_UPLOAD_TEMP_DIR')+'/'+tmp_file.name

        destination = open(file_path, 'wb+')
        for chunk in tmp_file.chunks():
            destination.write(chunk)
        destination.close()

        try:
            audio = MP3(file_path)
            if audio.info.length > 300:
                os.remove(file_path)
                raise forms.ValidationError("MP3 is too long.")

        except (HeaderNotFoundError, InvalidMPEGHeader):
            os.remove(file_path)
            raise forms.ValidationError("File is not valid MP3 CBR/VBR format.")
        os.remove(file_path)
        return args