Django: view downloads in general view

Therefore, I want to upload a couple of mp3 files from the folder to /home/username/music . I didnโ€™t think it would be so important, but I got a little confused how to do this using common views and my own URL.

urls.py

 url(r'^song/(?P<song_id>\d+)/download/$', song_download, name='song_download'), 

The example that I follow is in the general view section of the Django documentation: http://docs.djangoproject.com/en/dev/topics/generic-views/ (below)

I am not 100% sure how to adapt this to my needs. Here is my views.py

 def song_download(request, song_id): song = Song.objects.get(id=song_id) response = object_detail( request, object_id = song_id, mimetype = "audio/mpeg", ) response['Content-Disposition'= "attachment; filename=%s - %s.mp3" % (song.artist, song.title) return response 

I'm actually at a loss how to convey that I want him to spit out my mp3 instead of what he is doing now - output .mp3 with all current pages containing html. Should my template be my mp3? Do I need to configure apache to serve files, or can Django extract mp3 from the file system (of course, the appropriate permissions) and maintain it? If you need to configure Apache, how do I tell Django about this?

Thanks in advance. All these files are located on the hard drive, so I donโ€™t need to โ€œgenerateโ€ anything in place, and I would like to prevent the disclosure of the location of these files, if possible. A simple / song / 1234 / download would be fantastic.

+7
python file django
source share
3 answers

Why do you want to do this with a general view? This is very easy to do without a general idea:

 from django.http import HttpResponse def song_download(request, song_id): song = Song.objects.get(id=song_id) fsock = open('/path/to/file.mp3', 'r') response = HttpResponse(fsock, content_type='audio/mpeg') response['Content-Disposition'] = "attachment; filename=%s - %s.mp3" % \ (song.artist, song.title) return response 

I am not sure if it is possible to do this work somehow with a general view. But in any case, using one is redundant here. If there is no template to display, the context automatically provided by the general view is useless.

+15
source share

To summarize my comment to Tomas Zelinsky in a real answer:

For several reasons, it's really best for apache / nginx / etc to do the job of sending files. Most servers have mechanisms to help with this utility: Apache and lighttpd have xsendfile, nginx has X-Accel-Redirect.

The idea is that you can use all the django features, such as good URLs, authentication methods, etc., but let the server do the work with the files. What your django behavior should look like is to return a response with a special header. Then the server will replace the response with the actual file.

Example for apache:

 def song_download(request): path = '/path/to/file.mp3' response = HttpResponse() response['X-Sendfile'] = smart_str(path) response['Content-Type'] = "audio/mpeg" response['Content-Length'] = os.stat(path).st_size return response 
  • set mode_xsendfile
  • add XSendFileOn on and (depending on version) XSendFileAllowAbove on or XSendFilePath the/path/to/serve/from to your apache configuration.

This way you do not discover the location of the file and do not retain all URL control in django.

+6
source share

Serving static files with Django is a bad idea, use Apache, nginx, etc.

https://docs.djangoproject.com/en/dev/howto/static-files/deployment/

+1
source share

All Articles