【问题标题】:Django's FileField "upload_to" method not called when calling save() with commit=False使用 commit=False 调用 save() 时未调用 Django 的 FileField“upload_to”方法
【发布时间】:2015-10-24 06:06:35
【问题描述】:

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

以下是一些相关代码:

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 类型。 (感谢丹尼尔)

【问题讨论】:

    标签: python django


    【解决方案1】:

    docs 声明如下

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

    所以你没有错。在提交之前它不会存在。

    如果您想在保存文件之前以某种方式处理文件。当它是一个临时文件时,你会想要访问它。 This answer 可以帮助您以这种替代方式访问文件以获取 mimetype 等。

    【讨论】:

      猜你喜欢
      • 2019-08-18
      • 2018-09-24
      • 2010-11-02
      • 2018-11-08
      • 2021-02-28
      • 2011-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多