在原有音乐播放器功能基础上,增加上传音乐功能。
效果:
目录
配置上传路径
配置路由
视图处理歌曲
引入类库
保存歌曲文件
模板上传
设置菜单列表
设置菜单列表样式
脚本设置
上传效果
1.显示菜单列表
2.点击上传歌曲
3.上传完成
4.查看保存文件
增加数据库操作
修改验证入库方法
修改歌曲加载方法
上传歌曲入库
总结
配置上传路径
在mymp3/settings.py文件中,最底下加上以下配置:
MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
配置路由
path(r'upload_music', views.upload_music, name='upload_music'),
视图处理歌曲
文件上传时,文件数据存储在request.FILES属性中。
注意:from表单上传文件需要加 enctype=”multipare/form-data”
上传必须是post请求。
引入类库
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
保存歌曲文件
通过csrf_exempt装饰器豁免csrf验证,读取模板提交的文件并写入设置的路径中。
@csrf_exempt
def upload_music(request):""" 上传歌曲文件 """if request.method == 'POST':file = request.FILES['file']# 文件在服务端路径 获取配置filePath = os.path.join(settings.MEDIA_ROOT, file.name)# 保存文件with open(filePath, 'wb+') as fp:for info in file.chunks():fp.write(info)return JsonResponse({'code': 1, 'msg': '上传成功!'})else:return JsonResponse({'code': 0, 'msg': '请选择POST提交文件!'})
模板上传
使用layui的文件上传功能来进行上传歌曲文件;原来加载歌曲使用的是下拉菜单,但是无法绑定layui上传事件,就改为自己写菜单列表了。
设置菜单列表
去掉原来的功能列表设置,改为在歌曲列表元素上面添加菜单列表内容。
菜单列表如下:
<!--菜单列表-->
<div id="menu-open"><span class="layui-icon layui-icon-app menu-open"></span><ul class="menu-list none"><li class="loadMusic">加载歌曲</li><li class="uploadMusic">上传歌曲</li></ul>
</div>
<!--菜单列表-->
设置菜单列表样式
通过给最外层的播放器容器设置相对浮动,菜单列表设置绝对浮动,调试后还是原来的位置。
<style>.none {display: none;}#music-player{position:relative;}#menu-open {position:absolute;top:24px;right:35px;}#menu-open span{color:#fff;}.menu-list {position:absolute;top:18px;right:-82px;margin: 5px 0;background-color:#fff;}.menu-list li{line-height: 26px;color: rgba(0,0,0,.8);font-size: 14px;white-space: nowrap;cursor: pointer;padding:0 20px;}
</style>
脚本设置
因为功能列表修改为菜单列表了,并在原来基础上增加上传功能绑定,故脚本修改较大。
内容如下:
layui.use(['dropdown', 'util', 'layer', 'table'], function () {var dropdown = layui.dropdown, util = layui.util, layer = layui.layer, $ = layui.jquery, upload = layui.upload;// 上传音乐var uploadInst = upload.render({elem: '.uploadMusic', url: '/upload_music',accept: 'audio',exts: 'mp3', done: function (res) {if(res.code > 0) {layer.alert(res.msg, {icon: 1})} else {layer.alert(res.msg, {icon: 5})}}, error: function () {layer.alert('请求异常', {icon: 5})}});// 打开菜单列表$("#menu-open").on('click', function () {$(".menu-list").toggleClass("none");})// 关闭菜单列表 点击菜单列表外的其他部分时关闭菜单列表$(document).on('click', function (e) {if ($(e.target).closest('.music-player').length < 1) {$('.menu-list').addClass("none");}})// 请求接口 导入歌曲到数据库$('.loadMusic').click(function(){$.ajax({type: 'GET',url: "/load_music",data: {id:1},success: function (data) {layer.alert(data, {icon: 1})}.bind(this),error: function (e) {console.log("ERROR : ", e);}});})})
上传效果
1.显示菜单列表
2.点击上传歌曲
3.上传完成
4.查看保存文件
增加数据库操作
目前只是实现文件上传功能,还需要把对文件进行验证和把相应歌曲信息加入数据库,这样播放列表就能显示和播放该歌曲了。
修改验证入库方法
把原来的insert_music方法改为两个方法,一个负责验证歌曲信息,另一个负责入库操作;并修改函数返回格式。
如下:
def auth_music(name):""" 验证歌曲文件 """ext = 'mp3'# 判断文件后缀fileInfo = name.split('.')if len(fileInfo) != 2:return {'code': 0, 'msg': '文件有误'}if fileInfo[1] != ext:return {'code': 0, 'msg': '请上传MP3文件'}# 查询歌曲是否存在info = Single.objects.filter(title=name).first()if info:return {'code': 0, 'msg': '歌曲已存在'}else:return {'code': 1, 'msg': '可以上传'}def insert_music(name):""" 把歌曲信息插入数据表 """single = Single()single.title = namesigners = name.split('-')single_1 = signers[1].strip('') if len(signers) > 1 else '未知'single.singer = single_1.strip('.mp3')single.songUrl = '/static/media/' + name# 随机1-10专辑封面图片sui_num = random.randint(1, 10)single.imageUrl = '/static/images/' + str(sui_num) + '.png'flag = single.save()if flag:return {'code': 0, 'msg': '上传失败,请重试!'}else:return {'code': 1, 'msg': '上传成功'}
修改歌曲加载方法
因为上述方法歌曲加载功能有使用,所以也需要相应修改,具体为:在循环中调用验证歌曲信息函数,通过判断返回值决定是否入库操作。
def load_music(request):""" 加载本地的歌曲 """# 项目路径app_path = os.path.abspath(os.path.dirname(__file__))# 获取媒体资源目录下所有歌曲文件path = app_path + '/../static/media/'files = os.listdir(path)for file in files:flag = auth_music(file)if flag['code'] > 0:print(insert_music(file))else:print(flag['msg'])return HttpResponse('加载本地音乐成功!')
上传歌曲入库
修改歌曲验证和入库方法就是为了方法通用,这样上传文件直接可以使用,并返回提示信息。
@csrf_exempt
def upload_music(request):""" 上传歌曲文件 """if request.method == 'POST':file = request.FILES['file']flag = auth_music(file.name)if flag['code'] < 1:return JsonResponse(flag)# 文件在服务端路径 获取配置filePath = os.path.join(settings.MEDIA_ROOT, file.name)# 保存文件with open(filePath, 'wb+') as fp:for info in file.chunks():fp.write(info)# 入库操作flag = insert_music(file.name)return JsonResponse(flag)else:return JsonResponse({'code': 0, 'msg': '请选择POST提交文件!'})
注意:通过request.FILES获取的文件,此时也就是file为文件对象,如果入库需要使用file获取文件名称来入库。
音乐播放器版本2源码
链接:百度网盘 请输入提取码
提取码:e5th
总结
在原来基础上增加单独歌曲文件上传,使用了layui控件实现上传,
后端验证歌曲文件,保存本地并入库处理。