使用commit = False

时间:2015-08-01 19:02:57

标签: python django

上下文:我想获取用户上传的文件,将其附加到模型,更改一些属性,然后将对象保存到数据库。

以下是一些相关代码:

models.py

def file_upload_path(instance, filename):
    path = os.path.join('uploaded_files', str(uuid4()))
    return path 

class UploadedFile(models.Model):
    file_object = models.FileField(null=False, blank=False,
                                   upload_to=file_upload_path)

    def __unicode__(self):
        return self.file_object.name

forms.py

class UploadFileForm(forms.ModelForm):
    class Meta:
        model = UploadedFile
        fields = ['file_object']

views.py

def home(request):
...
        if form.is_valid():
            new_file = form.save(commit=True)

            print new_file
...

此代码打印出我想要的内容,即在调用upload_to并将文件保存到所述位置后的文件路径(例如“uploaded_files / b992e44e-6403-4c37-82b4-b3c403d07f79”)。

现在,有了这个views.py,事情发生了变化:

views.py

def home(request):
...
        if form.is_valid():
            new_file = form.save(commit=False)

            print new_file

            # new_file_object = FileObject(os.path.abspath(new_file.file_object.url))
            # new_file.mime_type = new_file_object.get_mime_type()
...

而不是路径,我得到原始文件名(例如“jnes.exe”),所以我无法处理文件,所以我可以得到它的mime类型,例如,然后更新模型并保存它数据库。

任何想法我做错了什么?感谢。

我是如何解决它的:

我对仍在内存中/临时在磁盘上的文件进行必要的模型编辑,因为Django不允许您直接找到FileField的位置,直到您实际保存新模型实例。

forms.py

def save(self, commit=True, *args, **kwargs):
    new_model = super(UploadFileForm, self).save(commit=False)

    file_object = self.cleaned_data['file_object']

    file_info = FileObject(file_object)

    new_model.mime_type = file_info.get_mime_type()
    new_model.sha256 = file_info.get_sha256()
    new_model.md5 = file_info.get_md5()

    if commit:
        new_model.save()

    return new_model

我通过从Django的UploadedFile临时对象读取数据,在FileObject的构造函数中获取哈希和mime类型。 (感谢丹尼尔)

1 个答案:

答案 0 :(得分:1)

docs说明以下

  

该文件是作为将模型保存在数据库中的一部分保存的,因此在保存模型之前,不能依赖磁盘上使用的实际文件名。

所以你没有错。在它被提交之前它不会在那里。

如果要在保存之前以某种方式处理文件。您想要在临时文件时访问它。 This answer可以帮助您使用这种替代方式来访问文件以获取mimetype等。