[英]Dynamic path for django FileSystemStorage
I was trying to save some files using Django FileSystemStorage. 我试图使用Django FileSystemStorage保存一些文件。 My model is as shown below
我的模型如下所示
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)
But when I save an object of this model only the file name is stored in the db. 但是当我保存此模型的对象时,只有文件名存储在db中。
So when I try to access the path it returns path appended with todays date and not as the uploaded date. 因此,当我尝试访问路径时,它返回附加了今天日期的路径,而不是上传日期。 ie.
即。 If I upload a file on say 09-21-2015 and I try to access the path on the next day it will return
account/files/09-22-2015/<file_name>
which will be an invalid path. 如果我在09-21-2015上传文件并且我尝试在第二天访问路径它将返回
account/files/09-22-2015/<file_name>
,这将是无效路径。 So what tweak should be made to store absolute path in db. 那么应该做什么调整来存储db中的绝对路径。 Or what am I doing wrong here?
或者我在这里做错了什么?
I'm pretty sure, your version does not do what you intend it to: 我很确定,你的版本不符合你的意图:
key_store = FileSystemStorage(
location='account/files/'+datetime.date.today().isoformat()
)
is evaluated when the module is loaded (usually only when you start your application). 在加载模块时评估(通常仅在您启动应用程序时)。 After that the date stays fixed as long as the module is not re-loaded.
之后,只要未重新加载模块,日期就会保持固定。 Hence it points to a directory with the name of the date the application was started, which is probably not what you want.
因此,它指向一个目录,其中包含应用程序启动日期的名称,这可能不是您想要的。
Also, FileSystemStorage
serializes with full path name, meaning that this also triggers a migration every other day (because the storage path changed). 此外,
FileSystemStorage
使用完整路径名序列化,这意味着这也会每隔一天触发一次迁移(因为存储路径已更改)。
You can solve this problem by using a combination of FileSystemStorage
(to store files outside of the media directory) and upload_to
with a callable: 您可以通过使用
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)
This uses a new FileSystemStorage
for the base directory of uploaded files and upload_to
to determine the name of an uploaded file relative to the storage's root. 这将使用新的
FileSystemStorage
作为上载文件的基本目录,使用upload_to
来确定相对于存储根目录的上载文件的名称。
Edit 1 : Thanks for pointing out that upload_to
takes a date format. 编辑1 :感谢您指出
upload_to
采用日期格式。
Since upload_to
also takes strftime()
format specifiers, a pure-date related path choice can also be implemented without the callable: 由于
upload_to
也采用strftime()
格式说明符,因此也可以在没有可调用的情况下实现与纯数据相关的路径选择:
info_file = models.FileField(storage=key_store, upload_to='account/files/%Y-%m-%d')
As for explanation: 至于解释:
A storage is essentially an abstraction of a hierarchical file system in django. 存储本质上是django中分层文件系统的抽象。
FileField
s always store their files in a storage . FileField
始终将其文件存储在存储中 。 By default the media storage is used, but that can be changed. 默认情况下,使用媒体存储 ,但可以更改。
To determine the path a file is uploaded to, FileField
roughly does the following 要确定文件上载的路径,
FileField
大致执行以下操作
upload_to
option specified for the file field. upload_to
选项。 If upload_to
is a string, use this string as a base directory. upload_to
是字符串,请将此字符串用作基目录。 upload_to
is run through strftime()
to process any date specifiers. upload_to
通过strftime()
运行以处理任何日期说明符。 Concatenate upload_to
and the request path, which results in a target path relative to the storage. upload_to
和请求路径,这将导致相对于存储的目标路径。 upload_to
is a callable, call it with (instance, request_path)
and use the return value as the target path (relative to the storage). upload_to
是可调用的,则使用(instance, request_path)
调用它,并使用返回值作为目标路径(相对于存储)。 As one can see, the storage is meant to be more or less static. 可以看出,存储意味着或多或少是静态的。 Changing the storage potentially invalidates all existing file paths in the database, because they are relative to the storage.
更改存储可能会使数据库中的所有现有文件路径无效,因为它们与存储相关。
Solved the same problem. 解决了同样的问题。 It uploads the file from the local machine to server
它将文件从本地计算机上载到服务器
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.