Pyexcel,加载一个文件在内存中创建一本书

Pyexcel, loading a file to create a book in memory

已解决;感谢@vmontco 的解决方案:我丢失了 MEDIA_URL,现在它完美运行了。 ----------下面的原始问题------------

我欢迎来自各个角度的建议;我对 Django 和 Python 还很陌生。我确定我遗漏了一些简单的东西。

使用模型表单和 FileField,我将 Excel 文件上传并保存到 MEDIA_ROOT 下的文件夹结构中。这行得通。

我想稍后读取同一个文件以使用 Pyexcel 执行操作。这就是我被困的地方。我正在尝试使用存储在数据库中的 FileField 上传文件。

这是我遇到问题的地方,我不确定是我误解了 MEDIA_ROOT,还是 Django 的其他方面。

当我将 pk 传递给第二个视图时,我会根据模型实例化一个对象。它有 FileField 'docfile',我正试图用它来访问文件以使用 Pyexcel 进行一些操作,

这是来自 models.py 的 FileField 声明:

docfile = models.FileField(
    verbose_name="Choose file to upload:", 
    upload_to='Excel_CSV_Assets/%Y/%m/%d')

编辑:如果我像这样将 pth 硬编码到文件中,一切正常,包括之后的操作:

thedocfile='site_static/site/original_assets/Excel_CSV_Assets/2016/04/23/Animals_oglc4DV.xlsx'
book=pyexcel.get_book(file_name=thedocfile)

:编辑结束

这是第二个视图中的代码,我尝试将文件读入内存,并使用 Pyexcel 创建一个 'book' class 对象。我被困在这里:

asset = Excel_CSV_Asset.objects.get(id=assetid)
book=pyexcel.get_book(file_name=asset.docfile)

这是我的错误描述:

这是我的代码中断处的信息:

虽然它说 "Wrong filename",但我可以看到该文件在文件夹中:

我可以通过双击打开文件;文件没有损坏。

编辑: 如果我将 'asset.docfile' 转换为 str,就像这样:

asset = Excel_CSV_Asset.objects.get(id=assetid)
book=pyexcel.get_book(file_name=str(asset.docfile))

我得到一个不同的错误:

[Errno 2] No such file or directory: 'Excel_CSV_Assets/2016/04/23/Animals_oglc4DV.xlsx'

...但这是正确的目录,位于 MEDIA_ROOT 文件结构下方。

这里是settings.py MEDIA_ROOT:

MEDIA_ROOT = 'site_static/site/original_assets/'

这里是urls.py:

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^e/', include('excel_to_mongo.urls')),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

这是该应用程序的 url.py:

url(r'^efactory/(?P<assetid>\d+)/$', 'display_sheet_column_choices', {}),

我认为你的问题是你没有完全理解 Django 的媒体文件管理。

什么是媒体文件?

媒体文件是用户上传的所有文件(在 运行 时间)。

您一定不要将它们与静态文件混淆,静态文件是您的项目工作所需的资产,并且是您在开发时添加的(例如CSS、背景图片和 JS 文件)。

您不应该混合使用它们,因为服务器对它们进行不同的管理,这可能会导致安全问题(参见警告 here:

静态文件管理:

您将 静态文件 作为代码的一部分放在已安装的 django 应用程序的一个 static 子目录中,或者放在您添加到的位置之一STATICFILES_DIRS.

必须在启动服务器之前通过调用 ./manage.py collectstatic, this command will collect (copy) the static files into the a directory (STATIC_ROOT 的值收集静态文件。

然后您必须设置 STATIC_URL 以选择 url 您应该提供静态文件。通常的选择是 /static/。要访问静态文件,您应该尝试访问 /static/path/to/static/file/in/static_root/dir.

媒体文件管理:

您的 媒体文件 已在 运行 时添加。它们存储在 MEDIA_ROOT location that has to be an absolute path 中。因此,我建议您加入 BASE_DIR 值(绝对路径)和您选择的子目录,例如:

MEDIA_ROOT = os.path.join(BASE_DIR, "/media/subdir")

然后您必须使用 MEDIA_URL 变量为媒体文件设置 URL。要访问您的媒体文件,urls 将以您选择的值开头:

MEDIA_URL = '/media/'

然后,将其添加到您的 urls.py 文件中:

if settings.DEBUG:
    urlpatterns = urlpatterns + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

在当前示例中,您的 mymediafile.txt 将位于 /path/to/your/project/media/subdir/path/in/media/root/mymediafile.txt 并在 http://127.0.0.1:8000/media/path/in/media/root/mymediafile.txt 投放。

但这仅适用于开发用途 here。这仅适用于 DEBUG == TRUE

对于生产用途,您应该考虑 deploying your media files 使用您的 http 服务器(例如 apache)。

结论:

花时间了解这一点。因为我怀疑你并没有真正理解你所做的事情,而这种理解的缺乏可能会导致未来的错误和错误。