繁体   English   中英

django FileSystemStorage的动态路径

[英]Dynamic path for django FileSystemStorage

我试图使用Django FileSystemStorage保存一些文件。 我的模型如下所示

key_store = FileSystemStorage(
location='account/files/'+datetime.date.today().isoformat())


class Account(models.Model):
    name = models.CharField(max_length=100, null=True, blank=True)
    user = models.ForeignKey(User, related_name='auth_user_account_relation')
    subscription_id = models.CharField(max_length=100, null=True, blank=True)
    info_file = models.FileField(storage=key_store)

但是当我保存此模型的对象时,只有文件名存储在db中。

因此,当我尝试访问路径时,它返回附加了今天日期的路径,而不是上传日期。 即。 如果我在09-21-2015上传文件并且我尝试在第二天访问路径它将返回account/files/09-22-2015/<file_name> ,这将是无效路径。 那么应该做什么调整来存储db中的绝对路径。 或者我在这里做错了什么?

我很确定,你的版本不符合你的意图:

key_store = FileSystemStorage(
    location='account/files/'+datetime.date.today().isoformat()
)

在加载模块时评估(通常仅在您启动应用程序时)。 之后,只要未重新加载模块,日期就会保持固定。 因此,它指向一个目录,其中包含应用程序启动日期的名称,这可能不是您想要的。

此外, FileSystemStorage使用完整路径名序列化,这意味着这也会每隔一天触发一次迁移(因为存储路径已更改)。

您可以通过使用FileSystemStorage (用于存储媒体目录之外的文件)和upload_to与可调用的组合来解决此问题:

key_store = FileSystemStorage(location='account/files/')

def key_store_upload_to(instance, path):
    # prepend date to path
    return os.path.join(
        datetime.date.today().isoformat(), 
        path
    )

class Account(models.Model):
    # [...]
    info_file = models.FileField(storage=key_store, upload_to=key_store_upload_to)

这将使用新的FileSystemStorage作为上载文件的基本目录,使用upload_to来确定相对于存储根目录的上载文件的名称。

编辑1 :感谢您指出upload_to采用日期格式。

由于upload_to也采用strftime()格式说明符,因此也可以在没有可调用的情况下实现与纯数据相关的路径选择:

info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')

至于解释:

存储本质上是django中分层文件系统的抽象。 FileField始终将其文件存储存储中 默认情况下,使用媒体存储 ,但可以更改。

要确定文件上载的路径, FileField大致执行以下操作

  1. 检索请求路径 ,该路径是文件上载的路径。
  2. 检查是否为文件字段指定了upload_to选项。 如果upload_to是字符串,请将此字符串用作基目录。 upload_to通过strftime()运行以处理任何日期说明符。 连接upload_to和请求路径,这将导致相对于存储的目标路径。
  3. 如果upload_to是可调用的,则使用(instance, request_path)调用它,并使用返回值作为目标路径(相对于存储)。
  4. 检查文件是否已存在于存储中。 如果是这样,则获得一条新的,独特的路径。
  5. 使用目标路径将文件保存到存储。
  6. 将目标路径(仍然相对于存储)存储在数据库中。

可以看出,存储意味着或多或少是静态的。 更改存储可能会使数据库中的所有现有文件路径无效,因为它们与存储相关。

解决了同样的问题。 它将文件从本地计算机上载到服务器
views.py

def receiveAudioRecord(request):

    if not os.path.exists('recording/wavFiles'):
        os.makedirs('recording/wavFiles')

    if not request.FILES['fileupload']:
        return render(request, "recording.html", {'msg': "Try Again! Unable to upload. </span>"})

    elif request.method == 'POST' and request.FILES['fileupload']:
        myfile = request.FILES['fileupload']
        fs = FileSystemStorage("recording/wavFiles")
        filename = fs.save(myfile.name, myfile)  # saves the file to `media` folder
        fs.url(filename)  # gets the url

        return render(request, "recording.html",{'msg':"successfully uploaded"})
    else:
        return render(request,"recording.html",{'msg':"Try Again! Unable to upload. </span>"})

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM