I'm quite new to using Django and I am trying to develop a website where the user is able to upload a number of excel files, these files are then stored in a media folder Webproject/project/media.
def upload(request):
if request.POST:
form = FileForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return render_to_response('project/upload_successful.html')
else:
form = FileForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('project/create.html', args)
The document is then displayed in a list along with any other document they have uploaded, which you can click into and it will displays basic info about them and the name of the excelfile they have uploaded. From here I want to be able to download the same excel file again using the link:
<a href="/project/download"> Download Document </a>
My urls are
urlpatterns = [
url(r'^$', ListView.as_view(queryset=Post.objects.all().order_by("-date")[:25],
template_name="project/project.html")),
url(r'^(?P<pk>\d+)$', DetailView.as_view(model=Post, template_name="project/post.html")),
url(r'^upload/$', upload),
url(r'^download/(?P<path>.*)$', serve, {'document root': settings.MEDIA_ROOT}),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
but I get the error, serve() got an unexpected keyword argument 'document root'. can anyone explain how to fix this?
OR
Explain how I can get the uploaded files to to be selected and served using
def download(request):
file_name = #get the filename of desired excel file
path_to_file = #get the path of desired excel file
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
If you hafe upload your file in media than:
media
example-input-file.txt
views.py
def download_csv(request):
file_path = os.path.join(settings.MEDIA_ROOT, 'example-input-file.txt')
if os.path.exists(file_path):
with open(file_path, 'rb') as fh:
response = HttpResponse(fh.read(), content_type="application/vnd.ms-excel")
response['Content-Disposition'] = 'inline; filename=' + os.path.basename(file_path)
return response
urls.py
path('download_csv/', views.download_csv, name='download_csv'),
download.html
a href="{% url 'download_csv' %}" download=""
I use this method:
{% if quote.myfile %}
<div class="">
<a role="button"
href="{{ quote.myfile.url }}"
download="{{ quote.myfile.url }}"
class="btn btn-light text-dark ml-0">
Download attachment
</a>
</div>
{% endif %}
When you upload a file using FileField
, the file will have a URL that you can use to point to the file and use HTML download
attribute to download that file you can simply do this.
models.py
The model.py looks like this
class CsvFile(models.Model):
csv_file = models.FileField(upload_to='documents')
views.py
#csv upload
class CsvUploadView(generic.CreateView):
model = CsvFile
fields = ['csv_file']
template_name = 'upload.html'
#csv download
class CsvDownloadView(generic.ListView):
model = CsvFile
fields = ['csv_file']
template_name = 'download.html'
Then in your templates.
#Upload template
upload.html
<div class="container">
<form action="#" method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.media }}
{{ form.as_p }}
<button class="btn btn-primary btn-sm" type="submit">Upload</button>
</form>
#download template
download.html
{% for document in object_list %}
<a href="{{ document.csv_file.url }}" download class="btn btn-dark float-right">Download</a>
{% endfor %}
I did not use forms, just rendered model but either way, FileField is there and it will work the same.
In view.py Implement function like,
def download(request, id):
obj = your_model_name.objects.get(id=id)
filename = obj.model_attribute_name.path
response = FileResponse(open(filename, 'rb'))
return response
I've found Django's FileField
to be really helpful for letting users upload and download files. The Django documentation has a section on managing files. You can store some information about the file in a table, along with a FileField
that points to the file itself. Then you can list the available files by searching the table.
Simple using html like this downloads the file mentioned using static keyword
<a href="{% static 'bt.docx' %}" class="btn btn-secondary px-4 py-2 btn-sm">Download CV</a>
You can add "download" attribute inside your tag to download files.
<a href="/project/download" download> Download Document </a>
Source: Stackoverflow.com