I followed these method to track how much downloaded the file was. But total_downloads
always remains same (it’s 0). How to increment total_downloads
field by 1 after every download?
My models.py:
from django.db import models class FilesAdmin(models.Model): id_no = models.IntegerField() name = models.CharField(max_length=20) loc = models.CharField(max_length=20) adminupload = models.FileField(upload_to='media') total_downloads = models.IntegerField(default=0) def __str__(self): return self.name
views.py. In this program, I want to increment the number of downloads. But it’s 0 in admin site.
from django.shortcuts import render from django.http import HttpResponse import os from .models import FilesAdmin def index(request): context = {'file': FilesAdmin.objects.all()} return render(request,'libooki/index.html',context) def download(request,path,pk): file_path = os.path.join(settings.MEDIA_ROOT,path) if os.path.exists(file_path): with open(file_path,'rb') as fh: response = HttpResponse(fh.read(),content_type="application/adminupload") response['Content-Disposition']='inline;filename'+os.path.basename(file_path) n = FilesAdmin.objects.get(pk=pk) n.total_downloads += 1 n.save() return response
urls.py
from django.contrib import admin from django.urls import include,path from django.conf import settings from django.conf.urls.static import static from libooki import views #here's libooki is my app name from django.conf.urls import url from django.views.static import serve urlpatterns = [ path('', views.index,name='index'), path('admin/', admin.site.urls), url(r'^download/(?P<path>.*)$',serve,{'document_root': settings.MEDIA_ROOT}), ] if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
index.html from where people can download the file
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> {% for post in file%} <h2>{{post.name}}</h2> <a href="{{post.adminupload.url}}" download="{{post.adminupload.url}}">Download</a> {% endfor %} </body> </html>
Advertisement
Answer
Try using Axios to download the file,
In the template, Try this-
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> {% for post in file %} <h2>{{post.name}}</h2> <button onclick="downloadFile('{{ post.adminupload.url }}', '{{ post.id }}')">Download file</button> {% endfor %} </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script> <script> function downloadFile(file_url, id) { axios({ method: "GET", url: file_url, responseType: 'blob', onDownloadProgress: event => { if (event.loaded === event.total) { // send a GET request to the backend telling that download is complete axios({ method: "GET", url: "/post-downloaded/" + id, // send id of the post, user is downloading }) .then(console.log("download incremented")) .catch(error => console.log(error)) } } }).then(response => { // download the file const aTag = document.createElement("a"); aTag.href = URL.createObjectURL(resp.data); aTag.download = "filename." + resp.data.type.split("/")[1]; aTag.click(); }) } </script> </html>
Now in the backend, create a route for /post-downloaded/
In your urls.py file-
from django.contrib import admin from django.urls import include, path from django.conf import settings from django.conf.urls.static import static from libooki import views from django.views.static import serve urlpatterns = [ path('', views.index,name='index'), path('post-downloaded/<int:pk>', views.post_downloaded), # add this route path('admin/', admin.site.urls), ] if settings.DEBUG: urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
And in the views.py file create this-
from django.shortcuts import render from django.http import HttpResponse from .models import FilesAdmin def index(request): context = {'file': FilesAdmin.objects.all()} return render(request,'libooki/index.html',context) def post_downloaded(request, pk): file = FilesAdmin.objects.get(pk=pk) file.total_downloads += 1 file.save() return HttpResponse("download added")
This should get the work done