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