首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Turbogears 2上传文件

使用Turbogears 2上传文件
EN

Stack Overflow用户
提问于 2010-03-04 05:54:36
回答 6查看 2.3K关注 0票数 6

我一直在试图找出用Turbogears 2管理文件上传的“最佳实践”,但到目前为止还没有找到任何例子。我已经想出了一种上传文件的方法,但我不确定它对我们有多可靠。

另外,获取上传文件名称的好方法是什么?

代码语言:javascript
复制
    file = request.POST['file']
    permanent_file = open(os.path.join(asset_dirname,
        file.filename.lstrip(os.sep)), 'w')
    shutil.copyfileobj(file.file, permanent_file)
    file.file.close()
    this_file = self.request.params["file"].filename 
    permanent_file.close()

因此,假设我的理解是正确的,像这样的东西能避免核心的“命名”问题吗?id = UUID。

代码语言:javascript
复制
    file = request.POST['file']
    permanent_file = open(os.path.join(asset_dirname,
        id.lstrip(os.sep)), 'w')
    shutil.copyfileobj(file.file, permanent_file)
    file.file.close()
    this_file = file.filename
    permanent_file.close()
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-03-05 16:07:43

@mhawke -你说得对,你必须处理它-取决于你正在对文件做什么,如果有名称冲突无关紧要,例如你只关心一些数据的最新版本,那么可能没有问题,或者如果文件名实际上并不重要,只是文件内容,但这仍然是一种糟糕的做法。

您可以在tmp目录中使用指定的临时文件,然后在验证后将该文件移动到其最终位置。或者您可以检查文件名是否已经存在,如下所示:

代码语言:javascript
复制
file.name = slugify(myfile.filename)
name, ext = os.path.splitext(file.name)
while os.path.exists(os.path.join(permanent_store, file.name)):
    name += '_'
    file.name = name + ext

raw_file = os.path.join(permanent_store, file.name)

slugify方法将用于整理文件名...

票数 2
EN

Stack Overflow用户

发布于 2015-04-20 17:39:58

我只想让任何来这里寻找答案的人都知道,Allesandro Molina的伟大的库Depot构成了这个问题的最佳答案。

它解决了命名和复制问题,并且可以很好地集成到您的TurboGears应用程序中。您可以将其与MongoDB GridFS一起使用,如下例所示:

代码语言:javascript
复制
from depot.manager import DepotManager

# Configure a *default* depot to store files on MongoDB GridFS
DepotManager.configure('default', {
    'depot.backend': 'depot.io.gridfs.GridFSStorage',
    'depot.mongouri': 'mongodb://localhost/db'
})

depot = DepotManager.get()

# Save the file and get the fileid
fileid = depot.create(open('/tmp/file.png'))

# Get the file back
stored_file = depot.get(fileid)
print stored_file.filename
print stored_file.content_type

或者,您可以轻松地在SQLAlchemy模型中创建附件字段,例如:

代码语言:javascript
复制
from depot.fields.sqlalchemy import UploadedFileField

class Document(Base):
    __tablename__ = 'document'

    uid = Column(Integer, autoincrement=True, primary_key=True)
    name = Column(Unicode(16), unique=True)

    content = Column(UploadedFileField)

…然后,存储带有附件的文档(源可以是文件或字节)就变得很容易了:

代码语言:javascript
复制
doc = Document(name=u'Foo', content=open('/tmp/document.xls'))
DBSession.add(doc)

Depot支持LocalFileStorageMongoDBGridFSStorage和亚马逊的S3Storage。而且,至少对于存储在本地和S3中的文件,fileid将由uuid.uuid1()生成。

票数 3
EN

Stack Overflow用户

发布于 2010-03-04 10:04:54

我对Turbogears了解不多,也不知道它是否能提供任何东西来避免以下情况,但在我看来,这段代码充满了危险。恶意用户可能会覆盖(或创建) Turbogears python进程有权写入的任何文件。

如果asset_dirname/tmpfile.filename的内容为../../../../../../../etc/passwd,文件的内容为root::0:0:root:/root:/bin/bash,该怎么办?在UNIX环境中,此代码(权限挂起)将以截断模式打开文件/tmp/../../../../../../../etc/passwd,然后将上载文件的内容复制到其中-有效地覆盖系统的密码文件并指定不带密码的根用户。大概在Windows机器上也可以做一些令人讨厌的事情。

好吧,这是一个极端的例子,它要求python以root身份运行(没有人这样做,不是吗?)即使python是以低权限用户身份运行的,以前上传的文件也可能被随意覆盖。

总而言之,不要相信用户输入,在这种情况下,用户提供的文件名在file.filename中可用。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2375290

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档