2

This is solved; thanks to @vmontco's solution: I was missing MEDIA_URL, now it works perfectly. ----------original question below-----------

I welcome suggestions from every angle; I am fairly new to Django and Python. I'm sure I am missing something simple.

Using a Model Form, with a FileField, I upload and save an Excel file to a folder structure under MEDIA_ROOT. This works.

I want to read that same file later to perform operations using Pyexcel. This is where I am stuck. I am attempting to upload the file using the FileField stored in the DB.

This is where I have problems, and I am not sure if am misunderstanding MEDIA_ROOT, or some other aspect of Django.

When I pass the pk to the 2nd view, I then instantiate an object based on the Model. It has the FileField 'docfile', which I am trying to use to access the file to do some operations using Pyexcel,

here is the FileField declaration from models.py:

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

EDIT: If I hard-code the pth to the file like this, everything works, including operations afterwards:

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

:END OF EDIT

Here is the code from the 2nd view, where I attempt to read the file into memory, and make a 'book' class object using Pyexcel. I am stuck here:

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

Here is my error description: wrong file name error

Here is the info right at where my code breaks: enter image description here

Although it says "Wrong filename", I can see the file is in the folder: file_location_name_and_properties

I'm able to open the file by double-clicking; the file is not corrupted.

EDIT: If I cast the 'asset.docfile' to str, like so:

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

I get a different error:

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

...but this is the correct directory, located beneath the MEDIA_ROOT file structure.

Here is settings.py MEDIA_ROOT:

MEDIA_ROOT = 'site_static/site/original_assets/'

Here is 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)

Here is the url.py of that app:

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

1 回答 1

1

我认为您的问题是您不完全了解 Django 的媒体文件管理。

什么是媒体文件?

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

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

您不应该混合它们,因为它们由服务器以不同方式管理,并且可能导致安全问题(参见此处的警告)

静态文件管理:

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

在启动服务器之前必须通过调用来./manage.py collectstatic收集静态文件,该命令会将静态文件收集(复制)到 a 目录(STATIC_ROOT的值)中。

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

媒体文件管理:

您的媒体文件是在运行时添加的。它们存储在必须是绝对路径MEDIA_ROOT的位置。因此,我建议您加入值(绝对路径)和您将选择的子目录,例如:BASE_DIR

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

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

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

但这仅适用于此处所述的开发用途。这仅适用于DEBUG == TRUE

对于生产用途,您应该考虑使用您的 http 服务器(例如 apache)部署媒体文件。

结论 :

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

于 2016-04-24T15:08:25.243 回答