2

Let me start by saying I have spent a lot of energy on this and any input is very valuable to me at this point. Now, onto my question:

What I have working: My website provides a simple interface for users to upload a file in which they will be given a key. The file is saved to the server and the key is generated using a modern, secure encryption algorithm. These details are not important to the question at hand.

What I want to implement: On a download page, the user can enter the key and the file will be downloaded to their computer. Want I want to know is how to provide a user with this ability to download an uploaded file. To put it simply, I just want to allow users to download a file in the MEDIA_ROOT folder.

I am using class-based views, so my urls are:

urls.py

from django.conf.urls import patterns, include, url
from django.conf.urls.static import static
from django.conf import settings
from fileupload.views import FileDownloadView, GetFileView

urlpatterns = patterns('',
    url(r'^key/?$', FileDownloadView.as_view(), name='getkey'),
    url(r'^download/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.MEDIA_ROOT}, GetFileView.as_view()),
) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Please provide me with the basic idea on what functions I should use in my views to actually download the file. I am still in development so I want to take advantage of Django's ability to serve files, not Apache's. I will consider other options if I go into production. Whatever code I need to post, I can post.

Thank you!

Chuck
  • 53
  • 2
  • 8
  • why not use nginx to handle all static files? – Ayush Nov 25 '15 at 22:31
  • Hello, I am sorry I forgot to mention I am using apache. I have added an edit to clarify that I want to take advantage of Django's ability to serve files. – Chuck Nov 25 '15 at 22:34

3 Answers3

1

If the key grants them access to the file, why not have the key be the file name? That is, when the file is uploaded, create a long key (say 64 characters long) and rename the file to the key name. Then simply serve up that file using the static.serve method when it is requested.

The benefits of this approach are: 1) You don't need to map the key to the file in the database, and 2) you don't need to validate the key when retrieving the file. If the file name is found, the key is valid.

Brent Washburne
  • 12,904
  • 4
  • 60
  • 82
  • Hi Brent, I am definitely doing this! It has definitely made the process easier. What I do not know is how to use this static.serve method to serve the file. Can you provide an example of how to use this function? Thanks. – Chuck Nov 25 '15 at 22:45
  • I have previously located this article and have setup everything accordingly, however, the article is missing the information on what methods do I need to use in my views. – Chuck Nov 25 '15 at 22:58
  • Here is the recommended solution: https://docs.djangoproject.com/en/1.8/howto/static-files/deployment/ – Brent Washburne Nov 25 '15 at 23:17
0

Basically I told you, Django should not serve files in production.

After is it possible yes:

You can serve a file tree with django.conf.urls.static.static(), as a view in your urls.py. Example:

urlpatterns = patterns('',
    ...
    static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    ...
)

Or use whitenoise, a package for server static file with Python web apps. It is very simple to use, only change your wsgi.py file like this:

from django.core.wsgi import get_wsgi_application
from whitenoise.django import DjangoWhiteNoise

application = get_wsgi_application()
application = DjangoWhiteNoise(application)

And use 'whitenoise.django.GzipManifestStaticFilesStorage' as STATICFILES_STORAGE.

Zulu
  • 8,765
  • 9
  • 49
  • 56
0

Along with the url file I have shown in the original question, all I needed to do from here was to provide an HttpResponseRedirect('/path/of/my/media/file')

Very simple!

Chuck
  • 53
  • 2
  • 8