在原有音乐播放器功能基础上,增加上传音乐功能。
效果:
目录
配置上传路径
配置路由
视图处理歌曲
引入类库
保存歌曲文件
模板上传
设置菜单列表
设置菜单列表样式
脚本设置
上传效果
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 = name
signers = 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控件实现上传,
后端验证歌曲文件,保存本地并入库处理。