I use this code in DJANGO framework to can some user download images.
this code work fine and download image every time to press download some user.
but this code download absolute images I need to zip this images for any user download.
def download_image(request, id):
product_image=MyModel.objects.get(pk=id)
product_image_url = product_image.upload.url
wrapper = FileWrapper(open(settings.MEDIA_ROOT+ product_image_url[6:], 'rb'))
content_type = mimetypes.guess_type(product_image_url)[0]
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = "attachment; filename=%s" % product_image_url
return response
is easy to change this code to download images in zip file ?
Try the following:
def download_image(request, id):
product_image=MyModel.objects.get(pk=id)
product_image_url = product_image.upload.url
image_path = settings.MEDIA_ROOT+ product_image_url[6:]
image_name = 'whatevername.png'; # Get your file name here.
with ZipFile('export.zip', 'w') as export_zip:
export_zip.write(image_path, image_name)
wrapper = FileWrapper(open('export.zip', 'rb'))
content_type = 'application/zip'
content_disposition = 'attachment; filename=export.zip'
response = HttpResponse(wrapper, content_type=content_type)
response['Content-Disposition'] = content_disposition
return response
Related
I'm trying to convert heic to png, which I successfully achieved in Python with the help of Wand library. I also saved the file locally to see, if the convertion worked, and it did. The problem is that Django's serializer cant take in Wand image, and I have to convert it to InMemoryUploadedFile. Whatever I do, I still can't make the serializator to take in the converted image.
views.py update_post()
#api_view(['PUT'])
#permission_classes([IsAuthenticated])
def update_post(request, id):
image = request.FILES['image']
print(image.size, image.name, image.file,
image.content_type, image.field_name)
if image.content_type == 'image/heif':
img = Image(file=image)
img.format = 'png'
img_io = io.BytesIO()
img.save(file=img_io)
filename = image.name.replace('.heic', '.png')
img.save(filename=filename)
img_file = InMemoryUploadedFile(
img_io,
'image',
filename,
'image/png',
sys.getsizeof(img_io),
None)
print(img_file.size, img_file.name, img_file.file,
img_file.content_type, img_file.field_name)
image = img_file
#request.data['image'] = img_file
#request.FILES['image'] = img_file
# data = request.data
# print(img_file, image)
loggedin_user = request.user.username
post = Post.objects.get(id=id)
post_user = post.user
if (str(post_user) == str(loggedin_user)):
serializer = PostSerializer(
instance=post, data={'caption': request.data['caption'], 'image': image})
if serializer.is_valid():
print(serializer.validated_data)
serializer.save()
else:
print('achjo')
print(serializer.data)
return Response(status=status.HTTP_200_OK)
I have used django-filter module for filtering. Want to export the results into CSV file.
def bfs_version_filter(request):
version_obj = bfs_versions.objects.all()
filter_obj = version_filter(request.GET, queryset = version_obj)
response = HttpResponse(content_type = 'text/csv')
file_name = "version_filter"+str(date.today())+".csv"
response['Content-Disposition'] = 'attachment; filename = "'+ file_name +'"' #edited by vennilam
writer = csv.writer(response)
for i in filter_obj:
writer.writerow(i)
return response
Getting below error:
TypeError at /bfslite/version_filter/
'version_filter' object is not iterable
Calling the constructor of a FilterSet subclass will not filter the queryset, it will construct an object of that subclass.
You can access the .qs attribute [readthedocs.io] to get access to the filtered queryset:
def bfs_version_filter(request):
version_obj = bfs_versions.objects.all()
filter_obj = version_filter(request.GET, queryset = version_obj).qs
response = HttpResponse(content_type = 'text/csv')
file_name = "version_filter"+str(date.today())+".csv"
response['Content-Disposition'] = 'attachment; filename = "'+ file_name +'"' #edited by vennilam
writer = csv.writer(response)
for i in filter_obj:
writer.writerow(i)
return response
I am trying to write the content in CSV file and Here I need to download that file and save that same file into upload folder. My code is below.
if request.method == 'POST':
param = request.POST.get('param')
report = Reactor.objects.all()
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename='+uuid.uuid4()+'.csv'
writer = csv.writer(response)
writer.writerow(['Name', 'Status', 'Date'])
for rec in report:
if rec.status == 1:
status = 'Start'
if rec.status == 0:
status = 'Stop'
if rec.status == 2:
status = 'Suspend'
writer.writerow([rec.rname, status, rec.date])
#return response
u = urllib.URLopener()
f = u.open(param)
open("down.txt","w").write(f.read())
pers = User.objects.get(pk=request.session['id'])
root = []
user_name = pers.uname
count = 1
root.append(
{'username': user_name,
'count': count
})
return render(request, 'plant/home.html',
{'user': root, 'count': 1})
Here I am setting the database values inside one CSV file and that file is named as unique id. Here I need to save that file inside Upload folder and that folder path will set inside settings.py file and also same file will be downloaded as well.
You should try to generate your CSV into a buffer an then use it to save it to the file system and use it again to return the CSV as the respone. Something like this
import csv
import os
import shutil
from io import StringIO
from django.http import HttpResponse
from django.conf import settings
def my_view(request):
csvbuffer = StringIO
writer = csv.writer(csvbuffer)
# Write data from the DB here into the CSV buffer
# Write the file to the file system
path = os.path.join(settings.FILE_PATH, "%s.csv" % uuid.uuid4())
with(path, 'w') as fd:
csvbuffer.seek(0)
shutil.copyfileobj(csvbuffer, fd)
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="somefilename.csv"'
csvbuffer.seek(0)
response.write(csvbuffer)
return response
I am quite sure this not the most optimized way to do it, but at least it should works.
I try to create an image from an url and save it in my django model. If the first part works fine, I do not know how to associate the generated file to my object.
This is my function to generate the image file:
def get_remote_image(image_url, merchant_product_path):
im = None
name = ''
r = requests.get(image_url, stream=True)
if r.status_code == 200:
name = urlparse(image_url).path.split('/')[-1]
full_path = os.path.join(settings.MEDIA_ROOT, merchant_product_path)
if not os.path.exists(full_path):
os.makedirs(full_path)
im = Image.open(r.raw)
if im.mode != "RGB":
im = im.convert("RGB")
im.thumbnail((500, 500), Image.ANTIALIAS)
im.save(full_path + name, 'JPEG')
return {'im': im, 'name': name}
And now, the part to associate this file to my object:
i = get_remote_image(row['pict'], m.get_products_media_path())
obj, created = ProductLine.objects.update_or_create(
...
...
...
)
if i['im'] is not None:
try:
obj.main_picture.save(
i['name'],
ContentFile(i['im']),
save=True)
except TypeError:
continue
This code works but unfortunately, mu pictures are created in the correct folder, objects are created/update but each one has no picture file :(
Can someone tell me what's wrong ?
I've finally found a solution:
def get_remote_image(image_url):
im = None
name = ''
r = requests.get(image_url, stream=True)
if r.status_code == 200:
name = urlparse(image_url).path.split('/')[-1]
i = Image.open(r.raw)
buffer = BytesIO()
if i.mode != "RGB":
i = i.convert("RGB")
i.thumbnail((500, 500), Image.ANTIALIAS)
i.save(buffer, format='JPEG')
im = InMemoryUploadedFile(
buffer,
None,
name,
'image/jpeg',
buffer.tell(),
None)
return {'im': im, 'name': name}
and then:
obj, created = ProductLine.objects.update_or_create(
...
...
...
)
i = get_remote_image(row['pict'])
obj.main_picture.save(
os.path.join(m.get_products_image_path(), i['name']),
i['im'],
save=True)
Hope this will help some other users in this situation.
With a model like :
class ProductLine(models.Model):
name = models.CharField(max_length=250, null=True)
image = models.ImageField(null=True)
You can directly link the picture on your computer using is path instead of his binary content.
obj, created = ProductLine.objects.update_or_create(...)
obj.image.name = "/path/to/the/file"
obj.save()
Here is the link i have used (Download files from Amazon S3 with Django). Using this i'm able to download single file.
Code:
s3_template_path = queryset.values('file')
filename = 'test.pdf'
conn = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = conn.get_bucket('your_bucket')
s3_file_path = bucket.get_key(s3_template_path)
response_headers = {
'response-content-type': 'application/force-download',
'response-content-disposition':'attachment;filename="%s"'% filename
}
url = s3_file_path.generate_url(60, 'GET',
response_headers=response_headers,
force_http=True)
return HttpResponseRedirect(url)
I need to download multiple files from S3, as a zip would be better. Can the mentioned method be modified and used. If not please suggest other method.
Okay here is a possible solution, it basically downloads each file and zips them into a folder, then returns this to the user.
Not sure if s3_template_path is the same for each file, but change this if neccessary
# python 3
import requests
import os
import zipfile
file_names = ['test.pdf', 'test2.pdf', 'test3.pdf']
# set up zip folder
zip_subdir = "download_folder"
zip_filename = zip_subdir + ".zip"
byte_stream = io.BytesIO()
zf = zipfile.ZipFile(byte_stream, "w")
for filename in file_names:
s3_template_path = queryset.values('file')
conn = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = conn.get_bucket('your_bucket')
s3_file_path = bucket.get_key(s3_template_path)
response_headers = {
'response-content-type': 'application/force-download',
'response-content-disposition':'attachment;filename="%s"'% filename
}
url = s3_file_path.generate_url(60, 'GET',
response_headers=response_headers,
force_http=True)
# download the file
file_response = requests.get(url)
if file_response.status_code == 200:
# create a copy of the file
f1 = open(filename , 'wb')
f1.write(file_response.content)
f1.close()
# write the file to the zip folder
fdir, fname = os.path.split(filename)
zip_path = os.path.join(zip_subdir, fname)
zf.write(filename, zip_path)
# close the zip folder and return
zf.close()
response = HttpResponse(byte_stream.getvalue(), content_type="application/x-zip-compressed")
response['Content-Disposition'] = 'attachment; filename=%s' % zip_filename
return response