Django音乐播放器:歌曲下载次数统计的更优方案咨询
实现歌曲下载次数统计的最优方案
直接通过后端处理下载请求来统计次数是更可靠的方案,能避免前端JS的各种不确定性,具体步骤如下:
1. 更新Song模型
首先给模型添加下载计数字段:
class Song(models.Model): """Model representing a song""" name = models.CharField( max_length=200, help_text=_('Enter a song name')) image = models.ImageField( upload_to='cover_image') content = models.FileField(upload_to='songs') artist = models.ForeignKey(User, on_delete=models.CASCADE) status = models.BooleanField( default=False, help_text=_('Check this box to make the song public') ) # 新增下载计数,默认初始值为0 download_count = models.PositiveIntegerField(default=0)
执行数据库迁移,让字段生效:
python manage.py makemigrations python manage.py migrate
2. 编写下载处理视图
在views.py中创建专门处理下载的视图,同时完成计数累加:
from django.http import FileResponse from django.shortcuts import get_object_or_404 from .models import Song from django.db.models import F def download_song(request, song_id): # 获取对应歌曲,不存在则返回404 song = get_object_or_404(Song, id=song_id) # 使用F表达式更新计数,避免多用户同时下载时的竞态计数错误 Song.objects.filter(id=song_id).update(download_count=F('download_count') + 1) # 返回文件下载响应,自动处理文件名和下载属性 response = FileResponse(song.content.open(), as_attachment=True, filename=song.name) return response
3. 配置URL路由
在项目或应用的urls.py中添加下载路由:
from django.urls import path from . import views urlpatterns = [ # 保留其他已有路由... path('download/<int:song_id>/', views.download_song, name='download_song'), ]
4. 修改模板中的下载链接
把原来直接指向媒体文件的a标签改成指向后端视图:
<a href="{% url 'download_song' i.id %}" class="btn btn-outline-danger"> Download Song </a>
方案优势
- 可靠性更高:无需依赖前端JS,即使用户禁用JS也能正常统计,同时避免了"点击下载但取消却计数"的前端逻辑漏洞
- 并发安全:使用Django的
F()表达式更新计数,避免多用户同时下载时的计数错误 - 代码更简洁:后端统一处理下载和计数逻辑,前端只需维护一个URL路由链接,减少冗余代码
内容的提问来源于stack exchange,提问作者Tran Minh Quan
相关产品推荐
相关产品推荐

