Python django文件系统存储的动态路径

Python django文件系统存储的动态路径,python,django,django-models,filefield,Python,Django,Django Models,Filefield,我试图用Django文件系统存储保存一些文件。我的模型如下所示 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

我试图用Django文件系统存储保存一些文件。我的模型如下所示

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)
但是当我保存这个模型的对象时,只有文件名存储在数据库中

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

我很肯定,你的版本没有达到你的目的:

key_store = FileSystemStorage(
    location='account/files/'+datetime.date.today().isoformat()
)
在加载模块时计算(通常仅在启动应用程序时)。之后,只要模块没有重新加载,日期就保持不变。因此,它指向一个目录,目录名为应用程序启动的日期,这可能不是您想要的

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

您可以结合使用
FileSystemStorage
(将文件存储在媒体目录之外)和
upload\u 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)
info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')
这将使用新的
FileSystemStorage
作为上载文件的基本目录,并使用
upload\u to
确定相对于存储根目录的上载文件的名称

编辑1:感谢您指出
upload\u to
采用日期格式

由于
upload\u to
还需要
strftime()
格式说明符,因此也可以实现纯日期相关路径选择,而无需调用:

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)
info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')
关于解释:

存储本质上是django中分层文件系统的抽象<代码>文件字段s始终将其文件存储在存储器中。默认情况下使用媒体存储,但可以更改

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

  • 检索请求路径,该路径是上载文件的路径
  • 检查是否为文件字段指定了
    upload\u to
    选项。 如果
    upload\u to
    是一个字符串,请将此字符串用作基本目录<通过
    strftime()
    运行code>upload\u to,以处理任何日期说明符。将
    upload_连接到
    和请求路径,从而生成相对于存储的目标路径
  • 如果
    upload\u to
    是可调用的,则使用
    (实例,请求路径)
    调用它,并使用返回值作为目标路径(相对于存储)
  • 检查该文件是否已存在于存储器中。如果是,则派生一个新的唯一路径
  • 使用目标路径将文件保存到存储器
  • 将目标路径(仍然相对于存储)存储在数据库中

  • 正如人们所看到的,存储或多或少是静态的。更改存储可能会使数据库中的所有现有文件路径无效,因为它们与存储相关。

    我很确定,您的版本没有达到您的预期:

    key_store = FileSystemStorage(
        location='account/files/'+datetime.date.today().isoformat()
    )
    
    在加载模块时计算(通常仅在启动应用程序时)。之后,只要模块没有重新加载,日期就保持不变。因此,它指向一个目录,目录名为应用程序启动的日期,这可能不是您想要的

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

    您可以结合使用
    FileSystemStorage
    (将文件存储在媒体目录之外)和
    upload\u 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)
    
    info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')
    
    这将使用新的
    FileSystemStorage
    作为上载文件的基本目录,并使用
    upload\u to
    确定相对于存储根目录的上载文件的名称

    编辑1:感谢您指出
    upload\u to
    采用日期格式

    由于
    upload\u to
    还需要
    strftime()
    格式说明符,因此也可以实现纯日期相关路径选择,而无需调用:

    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)
    
    info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')
    
    关于解释:

    存储本质上是django中分层文件系统的抽象<代码>文件字段s始终将其文件存储在存储器中。默认情况下使用媒体存储,但可以更改

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

  • 检索请求路径,该路径是上载文件的路径
  • 检查是否为文件字段指定了
    upload\u to
    选项。 如果
    upload\u to
    是一个字符串,请将此字符串用作基本目录<通过
    strftime()
    运行code>upload\u to,以处理任何日期说明符。将
    upload_连接到
    和请求路径,从而生成相对于存储的目标路径
  • 如果
    upload\u to
    是可调用的,则使用
    (实例,请求路径)
    调用它,并使用返回值作为目标路径(相对于存储)
  • 检查该文件是否已存在于存储器中。如果是,则派生一个新的唯一路径
  • 使用目标路径将文件保存到存储器
  • 将目标路径(仍然相对于存储)存储在数据库中

  • 正如人们所看到的,存储或多或少是静态的。更改存储可能会使数据库中的所有现有文件路径无效,因为它们与存储相关。

    解决了相同的问题。它将文件从本地计算机上载到服务器
    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>"})
    
    def接收音频记录(请求):
    如果不存在os.path.exists('recording/wavFiles'):
    os.makedirs('recording/wavfile')