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', {}),
sboggs11
  • 178
  • 1
  • 12
  • What is the absolute path to your file? What is the value of MEDIA_ROOT? – vmonteco Apr 24 '16 at 04:11
  • This is what I am using to place all media: MEDIA_ROOT = 'site_static/site/original_assets/' – sboggs11 Apr 24 '16 at 04:13
  • And the BASE_DIR? Could you paste exactly what you put in your settings.py? Do you have problems only with this kind of files or did you achieved something else with media files in your project? – vmonteco Apr 24 '16 at 04:15
  • BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) this is not showing the double__underscores on either side of 'file' but they are there. S.O. is filtering them out, I think. – sboggs11 Apr 24 '16 at 04:16
  • I have only been attempting Excel files – sboggs11 Apr 24 '16 at 04:17
  • And for MEDIA_ROOT? What did you put? – vmonteco Apr 24 '16 at 04:24
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/110041/discussion-between-sboggs10-and-vmonteco). – sboggs11 Apr 24 '16 at 04:24
  • @vmontco - Hey, I followed up a bit more with your mention of MEDIA_URL, set it to:'MEDIA_URL = 'site_static/site/original_assets/', and this works now, just like this: book=pyexcel.get_book(file_name=thedocfile) THANKS! if you post an answer per your suggestion I will mark it correct. Otherwise I will wait til tomorrow and answer myself with you in the credits. – sboggs11 Apr 24 '16 at 06:01
  • I'm glad you managed to make it work but I'll add my own answer only to give you advices and explanations about MEDIA files management. (No offence, but I think it is still needed. :) ) – vmonteco Apr 24 '16 at 14:17
  • No offense taken; spot on :) – sboggs11 Apr 24 '16 at 20:08

1 Answers1

1

I think your problem is that you don't fully understand the media files management with Django.

What are media files?

Media files are all the files that are user-uploaded (at running time).

You must not mistake them with Static files that are assets needed by your project to work and that you add at development time (CSS, background picture and JS files for instance).

You shouldn't mix them because they are managed differently by the server and that it could lead to security problems (cf. the warning here):

Static files management :

You put your static files as a part of the code either in one static subdirectory from the installed django applications, either in one of the locations you added to STATICFILES_DIRS.

Static files have to be gathered before starting the server by calling ./manage.py collectstatic, this command will collect (copy) the static files into the a directory (STATIC_ROOT's value).

You then have to set STATIC_URL to choose with wich url you should serve your static files. An usual choice would be /static/. To access the static file you should then try to reach /static/path/to/static/file/in/static_root/dir.

Media files management :

Your media files are added at running time. They are stored in the MEDIA_ROOT location that has to be an absolute path. Hence the fact I suggested you to join the BASE_DIR value (an absolute path) and the subdir you would choose with something like :

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

You then have to set an URL for your media files, by using the MEDIA_URL variable. To access your media files, the urls will start with the value you choose :

MEDIA_URL = '/media/'

Then, add this to your urls.py file :

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

With the current example, your mymediafile.txt will be located at /path/to/your/project/media/subdir/path/in/media/root/mymediafile.txt and served at http://127.0.0.1:8000/media/path/in/media/root/mymediafile.txt.

But this is suitable only for a development use as told here. And this would work only for DEBUG == TRUE

For a production use, you should consider deploying your media files with your http server (apache for instance).

Conclusion :

Take the time to understand this. Because I suspect you don't really understood what you did and this lack of understanding could lead to future bugs and errors.

vmonteco
  • 14,136
  • 15
  • 55
  • 86
  • @vmontco: This is extremely helpful- I will change these settings before moving to production servers, and after researching the design decisions I must make. – sboggs11 Apr 24 '16 at 20:05