我试图使用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中的绝对路径。或者我在这里做错了什么?
答案 0 :(得分:3)
我很确定,你的版本没有按照你的意图行事:
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')
至于解释:
storage 本质上是django中分层文件系统的抽象。 FileField
始终将其文件存储在存储中。默认情况下,使用媒体存储,但可以更改。
要确定文件上传到的路径,FileField
大致会执行以下操作
upload_to
选项。
如果upload_to
是字符串,请将此字符串用作基目录。 upload_to
运行strftime()
以处理任何日期说明符。连接upload_to
和请求路径,这将导致相对于存储的目标路径。upload_to
是可调用的,请使用(instance, request_path)
调用它,并使用返回值作为目标路径(相对于存储)。正如人们所看到的,存储意味着或多或少是静态的。更改存储可能会使数据库中的所有现有文件路径无效,因为它们与存储相关。
答案 1 :(得分:0)
解决了同样的问题。它将文件从本地机器上传到服务器
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>"})