代码之家  ›  专栏  ›  技术社区  ›  yspreen

从Django中的磁盘“上载”文件

  •  0
  • yspreen  · 技术社区  · 8 年前

    我用python生成一个文件,并希望将该文件“上载”到django数据库。这样,它会自动放入媒体文件夹,并与我的应用程序的所有其他文件整齐地组织在一起。

    # forms.py
    class UploadForm(forms.ModelForm):
        class Meta:
            model = UploadedFile
            fields = ('document',)
    
    # models.py
    class UploadedFile(models.Model):
        document = models.FileField(upload_to=get_upload_path)
    
        # mimetype is generated by filename on save
        mimetype = models.CharField(max_length=255)
    
        # ... additional fields like temporary
    
    def get_upload_path(instance: UploadedFile, filename):
        if instance.temporary:
            return "uploaded_files/temp/" + filename
        return "uploaded_files/" + filename
    
    # views.py, file_out has been generated
    with open(file_out, 'rb') as local_file:
        from django.core.files import File
        form = UploadForm(dict(), {'document': File(local_file)})
        print(form.errors)
        if form.is_valid():
            file = form.save(commit=False)
            # ... set additional fields
            file.save()
            form.save_m2m()
            return file
    

    这不是我唯一尝试过的事情。首先,我设置了 FileField save() 设置mimetype字段时失败。因为原始文件位于媒体文件夹之外,因此会触发可疑文件操作。

    此外,表格还通过 form.errors

    根据我的方法,要么 保存() 如上所述失败——意味着“上传”实际上并没有复制媒体文件夹中的文件——或者表单返回错误,即没有传输任何文件,并告诉检查表单协议。

    现在我的理论是,我必须去初始化我自己的 InMemoryUploadedFile

    2 回复  |  直到 8 年前
        1
  •  1
  •   Franey    8 年前

    你有 get_upload_path 定义如果没有,那就可以解释你所犯的错误。

    据我所知,你正走在正确的轨道上。如果你不需要上传动态路径,如果你只是想上传 media/uploads ,可以为传递字符串值 upload_to (来自 Django docs

    # file will be uploaded to MEDIA_ROOT/uploads
    document = models.FileField(upload_to='uploads/')
    
        2
  •  0
  •   yspreen    8 年前

    首先,感谢 Franey 因为你指着我 storage documentation contentfile documentation .

    ContentFile 实际上解决了这个问题,因为它基本上是的自实例化版本 InMemoryUploadedFile 我一直在寻找的。这是django File 未存储在磁盘上。

    # views.py, file_out has been generated
    with open(file_out, 'rb') as local_file:
        from django.core.files.base import ContentFile
    
        # we need to provide a name. Otherwise the Storage.save
        # method reveives a None-parameter and breaks.
        form = UploadForm(dict(), {'document': ContentFile(local_file.read(), name=name)})
        if form.is_valid():
            file = form.save(commit=False)
            # ... set additional fields
            file.save()
            form.save_m2m()
            return file