In django, how can i upload file via url? - django

Hi i'm making my own webserver using django.
i just want to upload local file to django server.
i google every method but i can't get answer.
every method using form or html but i don't want to using form and html
example : from www.localfolder/example.txt to /media/examplefolder.
i don't know how to do.. any help?
this is my code.
#csrf_exempt
def download_file(request, file):
fl_path = 'media/'
filename = str(file)
fl = open(fl_path, 'r')
mime_type, _ = mimetypes.guess_type(fl_path)
response = HttpResponse(fl, content_type=mime_type)
response['Content-Disposition'] = "attachment; filename = %s" % filename
return response

What did you search for when you googled? These were the top 2 results for Django files
https://docs.djangoproject.com/en/3.0/topics/http/file-uploads/
https://docs.djangoproject.com/en/3.0/topics/files/
Seems to have everything you are looking for.

Related

Django - Create and add multiple xml to zip, and download as attachment

I am learner, and trying to build code to in which user has option to download the zip file that contains multiple .xlm files, which are created on the bases of database.
I have been able to create below code to download single xml file. But struggling to get multiple files packed in zipped format(for each row of database).
import xml.etree.ElementTree as ET
def export_to_xml(request):
listings = mydatabase.objects.all()
root = ET.Element('listings')
for item in listings:
price = ET.Element('price')
price.text = str(item.Name)
offer = ET.Element('offer', attrib={'id': str(item.pk)})
offer.append(price)
root.append(offer)
tree = ET.ElementTree(root)
response = HttpResponse(ET.tostring(tree.getroot()), content_type='application/xhtml+xml')
response['Content-Disposition'] = 'attachment; filename="data.xml"'
return response
Hi Got the solution by using following approach
byteStream = io.BytesIO()
with zipfile.ZipFile(byteStream, mode='w',) as zf:
# your code
zf.writestr()
response = HttpResponse(byteStream.getvalue(), content_type='application/x-zip-compressed')
response['Content-Disposition'] = "attachment; filename=finename.zip"

Django output csv file, filename is not setting as the value of Content-Disposition

I want to download a csv file with custom filename in a django project, but somehow the downloaded filename just display as "download.csv" instead of using the value of filename in Content-Disposition. I also tried to print csv_response['Content-Disposition'] out, but I'm getting a very strange string =?utf-8?b?YXR0YWNobWVudDsgZmlsZW5hbWU9Iuivvueoi+aKpeWQjeaDheWGtV8yMDE5MTEyODA3NDI0Ny5jc3Yi?=
the code snippet is :
#action(detail=False, methods=['GET'])
def download(self, request):
registrations = self.filter_queryset(self.get_queryset())
csv_response = HttpResponse(content_type='text/csv')
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
time=time.strftime("%Y%m%d%H%M%S", time.localtime())
)
writer = csv.writer(csv_response)
writer.writerow([
some content,
])
for registration in registrations:
term_title = '{order} th'.format(order=registration.term.order)
course_title = registration.course.title
writer.writerow([
registration.user.email,
course_title,
term_title,
str(registration.confirmation_code),
str(registration.payment_due),
str(registration.payment_paid),
str(registration.source),
str(registration.created_at),
str(registration.updated_at),
str(registration.payment_source),
])
return csv_response
the django I am using is 2.2
any ideas why this is happening? I am a newb.
Thx in advance
The response header in chrome Dev tools:
I resolved the problem, by following the answer in the below post:
HttpResponse Django does not change file name
I guess that it is that because the string of Content-Disposition needs to be encoded, and if no, then somehow cannot operate on that, by using urlquote, it is solved.
Explanation about urlquote is here
UPDATE:
Also, a simpler way to resolve this without importing urlquote is to add encode(), like below:
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{time}.csv"'.format(
time=time.strftime("%Y%m%d%H%M%S", time.localtime())
).encode()
Change to this:
csv_response['Content-Disposition'] = 'attachment; filename="some_custom_name_{}.csv"'.format(
time.strftime("%Y%m%d%H%M%S", time.localtime())
)

Does Django Automatically Sanitise urls for directory traversal attacks?

I have a view in my Django web app like this :
def download_func(request, url):
file_url = '/home/mylaptop/myproject/' + url
file = open (file_url, "rb").read()
response = HttpResponse(file, content_type="application/octect-
stream")
response['Content-Disposition'] = 'attachment; filename = %s' %url
return response
and a url conf like this :
urlpatterns = [
...
url(r'^media/videos/(?P<url>[-._\w]+)/$', views.download_func),
...
]
Downloading a video that is uploaded before is perfectly working, but my question is: "Is there the risk of directory traversal attack in my app?"
if "yes" how can I fix it (or is there a better way of writting view for downloading while development?)
I have been testing directory traversal on it and understood that Django automatically sanitises urls containing "../../" is that right?
thanks

How to serve a django-webodt file to users?

I'm trying to allow users to export some of their database data. I am using django-webodt to create a .odt file from their data. I then am trying to allow them to download it. The file is created just fine, but when it downloads it seems to download a blank file. I think there is some difference between where the server is looking for the file and where it actually is. I was wondering how to get this to work properly? I'm relatively new to django so any help would be appreciated. The code I have is below:
def downloadBook(request, val):
template = webodt.ODFTemplate('conversion.odt')
context = dict(ideas=Book.objects.getIdeaSet(int(val)))
document = template.render(Context(context))
file_name = os.path.basename(document.name)
path_to_file = os.path.dirname(document.name)
response = HttpResponse(mimetype='application/force-download')
response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(file_name)
response['X-Sendfile'] = smart_str(path_to_file)
return response
I did the following and it works:
from django.template import Context
from webodt import ODFTemplate
template = ODFTemplate('template_file.odt')
context = { 'some_dict': '' }
document = template.render(Context(context))
response = HttpResponse(document.read(), mimetype='application/vnd.oasis.opendocument.text')
response['Content-Disposition'] = "attachment; filename=fancy-filename-as-you-like.odt"
document.close() # delete the document on /tmp
return response

Django download file empty

I am writing a simple function for downloading a certain file, from the server, to my machine.
The file is unique represented by its id. The file is locatd corectly, and the download is done, but the downloaded file (though named as the one on the server) is empty.
my download function looks like this:
def download_course(request, id):
course = Courses.objects.get(pk = id).course
path_to_file = 'root/cFolder'
filename = __file__ # Select your file here.
wrapper = FileWrapper(file(filename))
content_type = mimetypes.guess_type(filename)[0]
response = HttpResponse(wrapper, content_type = content_type)
response['Content-Length'] = os.path.getsize(filename)
response['Content-Disposition'] = 'attachment; filename=%s/' % smart_str(course)
return response
where can i be wrong? thanks!
I answered this question here, hope it helps.
Looks like you're not sending any data (you don't even open the file).
Django has a nice wrapper for sending files (code taken from djangosnippets.org):
def send_file(request):
"""
Send a file through Django without loading the whole file into
memory at once. The FileWrapper will turn the file object into an
iterator for chunks of 8KB.
"""
filename = __file__ # Select your file here.
wrapper = FileWrapper(file(filename))
response = HttpResponse(wrapper, content_type='text/plain')
response['Content-Length'] = os.path.getsize(filename)
return response
so you could use something like response = HttpResponse(FileWrapper(file(path_to_file)), mimetype='application/force-download').
If you are really using lighttpd (because of the "X-Sendfile" header), you should check the server and FastCGI configuration, I guess.
Try one of these approaches:
1) Disable GZipMiddleware if you are using it;
2) Apply a patch to django/core/servers/basehttp.py described in
https://code.djangoproject.com/ticket/6027