How to download a .txt file from a django project - django

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

Related

django export xls as zip doesn't work: format unknown

I want to make a view that produce xls file using xlwt and make file downloaded as zip file using zipfile.
def export(request):
filename = "myfile.xls"
wb = xlwt.Workbook(encoding='utf-8')
....
buffer1 = io.BytesIO()
wb.save(buffer1)
buffer2 = io.BytesIO()
with zipfile.ZipFile(buffer2, mode='w') as zip_file:
zip_file.writestr(zinfo_or_arcname=filename, data=buffer1.getvalue())
response = HttpResponse(content_type='application/x-zip-compressed')
response['Content-Disposition'] = 'attachment; filename=myzip.zip'
return response
but when I try to unzip I got an error: file format unknown

How to download a file using default_storage class in 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)

Do I need to write the full media path in Django?

I am trying to download a file that is stored in the media folder and it seems as it only works when I am writing the full path as:
file_location = '/home/user/user.pythonanywhere.com/media/'
In the settings page on pythonanywhere, the 'media url' points to the same directory. So I don't really understand why I just can't write /media/ instead for the full path.
Has it something to do with my settings.py file? I have these lines there:
MEDIA_ROOT= os.path.join(BASE_DIR, 'media')
MEDIA_URL="/media/"
Do I need to have these lines at all?
This is my download function:
class RequestFile(APIView):
def get(self, request):
#Returns the last uploaded file
#Remember if deleting files, only database record is deleted. The file must be deleted
obj = FileUploads.objects.all().order_by('-id')
file_location = '/home/user/user.pythonanywhere.com/media/' + str(obj[0].lastpkg)
x = file_location.find("/")
filename = file_location[x+1:]
print(file_location)
print(filename)
try:
with open(file_location, 'rb') as f:
filex_data = f.read()
#print("filex_data= ", filex_data)
# sending response
response = HttpResponse(filex_data, content_type='application/octet-stream')
response['Content-Disposition'] = 'attachment; filename=' + filename
except IOError:
# handle file not exist case here
response = HttpResponseNotFound('File not exist')
return response
If I go to the url that points to this class I will get the download.
From Django documentation
>>> car = Car.objects.get(name="57 Chevy")
>>> car.photo
<ImageFieldFile: cars/chevy.jpg>
>>> car.photo.name
'cars/chevy.jpg'
>>> car.photo.path
'/media/cars/chevy.jpg'
>>> car.photo.url
'http://media.example.com/cars/chevy.jpg'
So in your case something like
obj = FileUploads.objects.first()
try:
with open(obj.name_of_file_attribute.path, 'rb') as f:

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!

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