如何在Django中实现文件下载点击次数统计功能
Django文件下载计数功能实现方案
你当前使用文件字段直链的方式,请求不会经过Django业务逻辑层,自然无法触发下载计数更新,按以下三步改造即可:
1. 编写下载专属视图
视图需要完成「校验文件存在 → 原子更新下载计数 → 返回文件下载响应」三个核心逻辑,注意用F()表达式做数据库层面的原子更新,避免高并发场景下计数不准的问题。
在views.py中添加如下代码:
from django.http import FileResponse, Http404 from django.db.models import F from .models import RadioFile import os def audio_download(request, file_id): # 校验目标文件是否存在 try: audio_obj = RadioFile.objects.get(id=file_id) except RadioFile.DoesNotExist: raise Http404("请求的音频文件不存在") # 原子累加下载量,无需先读取字段值再保存,避免并发计数偏差 RadioFile.objects.filter(id=file_id).update(download_count=F('download_count') + 1) # 构造文件下载响应 file = audio_obj.audio_file.open('rb') response = FileResponse( file, as_attachment=True, filename=os.path.basename(audio_obj.audio_file.name) ) return response
2. 配置下载路由
在对应app的urls.py中添加路由映射,指向刚写的下载视图:
from django.urls import path from . import views urlpatterns = [ # 保留你原有的其他路由 path('download/audio/<int:file_id>/', views.audio_download, name='audio_download'), ]
3. 修改模板下载链接
把原来模板中直接指向文件直链的a标签,替换为Django反向解析的下载路由地址:
<th scope="row" style="vertical-align: middle;"> <a href="{% url 'audio_download' file_id=radio_file.id %}"> <i class="fas fa-download mr-2 text-danger"></i></a> </th> <td>{{ radio_file.download_count }} </td>
生产环境优化提示:如果站点访问量较大、音频文件体积偏大,不建议让Django直接处理文件传输。可以在视图完成计数更新后,通过
X-Accel-Redirect(Nginx环境)或X-Sendfile(Apache环境)头将文件返回逻辑交给前端Web服务器处理,既保留计数逻辑,性能也和直链下载基本一致。
内容的提问来源于stack exchange,提问作者PTB
相关产品推荐
相关产品推荐

