How to download a file using default_storage class in django - django

I am using Django default_storage API to save my media files.
I am able to save the file, and open the file for writing. But I am not able to download the file.
I used the code below to save the file:
default_storage.save(filename, ContentFile(str(a).encode()))
Is there any way to download the file in the same way?
I used the code below to download the file, but it is not either downloading or not throwing any error:
with default_storage.open(filepath, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
response['Content-Disposition'] = 'inline ; filename=' +os.path.basename(filepath)
return response
raise Http404

You are on the right path.
with default_storage.open(filepath, 'rb') as fh:
with open('my_local_file','wb') as wh:
data = fh.read() # You may want to split this into chunks..
wh.write(data)

Related

how to prompt user to save a pdf file to his local machine in django?

I am fairly new to Django and my project requires me to prompt user to open a pdf upon clicking a link. I already have the pdf file on my local machine and dont want to recreate it using Reportlab. Is there any way to do it?
I tried
with open("/user/some/directory/somefilename.pdf") as pdf:
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="somefilename.pdf"'
return response
but it returned 404 page not found as the requested url wasn't in the URLconf of myproject.urls
What am I missing?
In general, when user click "Download", you can:
- If file is not existed:
- Generate pdf file use ReportLab as you did.
- Store generated file to a public dir.
return HttpResponseRedirect(file_url_to_public_dir)
The way that worked for me is by using FileSystemStorage
from django.core.files.storage import FileSystemStorage
from django.http import HttpResponse
fs = FileSystemStorage("/Users/location/where/file/is_saved/")
with fs.open("somefile.pdf") as pdf:
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="my_pdf.pdf"'
return response
and now its prompting the user to save the file as it normally would!

How to download a .txt file from a django project

I find difficulty on how to download my .txt file after pressing the button which calls the view respnosible for that.
My .txt file is created locally in the path where my manage.py file resides.
snippet code of my view:
file_name= open("example.txt","w+")
file_name.write("\r\n\r\n%s%s%s%s%s" % (var1," ",var2," ",var3))
response = HttpResponse(file_name, content_type="text/plain,charset=utf8")
response['Content-Disposition'] = 'attachment; filename={0}'.format(file_name)
file_name.close()
return response
What i have to change to be able to download my .txt file?
try this in your view:
# to write to your file
file_name = open("example.txt", "w+")
file_name.write('some text here')
file_name.close()
# to read the content of it
read_file = open("example.txt", "r")
response = HttpResponse(read_file.read(), content_type="text/plain,charset=utf8")
read_file.close()
response['Content-Disposition'] = 'attachment; filename="{}.txt"'.format('file_name')
return response

django zip file doesn't get downloaded

I want to download zip files using Django views. I have gone through many solutions in stack overflow. But the file does not get downloaded at all. Here is the code I am using.
Could anyone, tell me where I am going wrong.
response = HttpResponse(mimetype='application/zip')
response['Content-Disposition'] = 'attachment; filename=%s' % doc[Zip_file_name]
response['X-Sendfile'] = "./Zipfiles" # the path where the zip files are stored
return response
In chrome, If I use inspect element, and double click on the url shown in the network tab, the file gets downloaded as it is recognized as a http get request, whereas on button click nothing happens.
Please Help.
from django.http import HttpResponse
from django.core.servers.basehttp import FileWrapper
# file
response = HttpResponse(FileWrapper(myfile), content_type='application/zip')
response['Content-Disposition'] = 'attachment; filename=myfile.zip'
return response

Django with mod_XSENDFILE unable to download complete file

Attached is the code which downloads a file from browser using django 1.3 and Apache 2.2 with mod_xsendfile
#login_required
def sendfile(request, productid):
path = settings.RESOURCES_DIR
filepath = os.path.join('C:/workspace/y/src/y/media/audio/','sleep_away.mp3')
print "filepath",filepath
filename = 'sleep_away.mp3' # Select your file here.
print "Within sendfile size", os.path.getsize(filepath)
wrapper = FileWrapper(open(filepath,'r'))
content_type = mimetypes.guess_type(filename)[0]
response = HttpResponse(wrapper, content_type = content_type)
print "Within wrapper"
from django.utils.encoding import smart_str
response['X-Sendfile'] = smart_str(filepath)
response['Content-Length'] = os.path.getsize(filepath)
from django.utils.encoding import smart_str
response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(filename)
return response
The console shows the following filesize which is the right size
Within sendfile size 4842585
But when I download/save the file it shows 107 KB...i.e 109,787 bytes.Where am I going wrong. Why isnt it downloading the complete file?
I consider your new to django or python. Try to put the import statements at the beginning of the method. Once imported it can be used through the method no need import every time you use. In windows you should use "rb" (read binary) to serve anything other than text files. Try not to use variable names that might conflict with method names or other keywords of the language. Your method should be like this
#login_required
def sendfile(request, productid):
from django.utils.encoding import smart_str
##set path and filename
resource_path = settings.RESOURCES_DIR # resource dir ie /workspace/y/src/y/media
filename = "sleep_away.mp3" #file to be served
##add it to os.path
filepath = os.path.join(resource_path,"audio",filename)
print "complete file path: ", filepath
##filewrapper to server in size of 8kb each until whole file is served
file_wrapper = FileWrapper(file(filepath,'rb')) ##windows needs rb (read binary) for non text files
##get file mimetype
file_mimetype = mimetypes.guess_type(filepath)
##create response with file_mimetype and file_wrapper
response = HttpResponse(content_type=file_mimetype, file_wrapper)
##set X-sendfile header with filepath
response['X-Sendfile'] = filepath ##no need for smart_str here.
##get filesize
print "sendfile size", os.stat(filepath).st_size
response['Content-Length'] = os.stat(filepath).st_size ##set content length
response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(filename) ##set disposition
return response ## all done, hurray!! return response :)
Hope that helps
You could have a look at the django-private-files project. Haven't tested it myself, but it looks promissing.
link to the docs --> http://readthedocs.org/docs/django-private-files/en/latest/usage.html
cheers

Programmatically Upload Files in Django

I have checked several other threads but I am still having a problem. I have a model that includes a FileField and I am generating semi-random instances for various purposes. However, I am having a problem uploading the files.
When I create a new file, it appears to work (the new instance is saved to the database), a file is created in the appropriate directory, but the file's content is missing or corrupt.
Here is the relevant code:
class UploadedFile(models.Model):
document = models.FileField(upload_to=PATH)
from django.core.files import File
doc = UploadedFile()
with open(filepath, 'wb+') as doc_file:
doc.documen.save(filename, File(doc_file), save=True)
doc.save()
Thank you!
Could it be as simple as the opening of the file. Since you opened the file in 'wb+' (write, binary, append) the handle is at the end of the file. try:
class UploadedFile(models.Model):
document = models.FileField(upload_to=PATH)
from django.core.files import File
doc = UploadedFile()
with open(filepath, 'rb') as doc_file:
doc.document.save(filename, File(doc_file), save=True)
doc.save()
Now its open at the beginning of the file.