Django implements a simple music player 4

On the basis of the original music player function, the function of uploading music is added.

 Effect:

Table of contents

Configure the upload path

configure routing

view processing song

import class library

save song file

template upload

Settings menu list

Set the menu list style

script settings

upload effect

1. Display menu list

2. Click to upload the song

3. Upload completed

4. View the saved file

Increase database operations

Modify the validation storage method

Modify the song loading method

Upload songs into library

Summarize


Configure the upload path

In the mymp3/settings.py file, add the following configuration at the bottom:

MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')

configure routing

path(r'upload_music', views.upload_music, name='upload_music'),

view processing song

When a file is uploaded, the file data is stored in the request.FILES property.

Note: uploading files from the form needs to add enctype="multipare/form-data"

Uploads must be post requests.

import class library

from django.conf import settings
from django.views.decorators.csrf import csrf_exempt

save song file

Exempt from csrf verification through the csrf_exempt decorator, read the file submitted by the template and write it into the set path.

@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提交文件!'})

template upload

Use the file upload function of layui to upload song files; the original loading song uses a drop-down menu, but the layui upload event cannot be bound, so I wrote the menu list myself.

Settings menu list

Remove the original function list setting, and add the menu list content above the song list element instead.

The menu list is as follows:

<!--菜单列表-->
<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>
<!--菜单列表-->

Set the menu list style

By setting relative floating for the outermost player container and setting absolute floating for the menu list, it is still in the original position after debugging.

<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>

script settings

Because the function list is changed to a menu list, and the upload function binding is added on the original basis, the script modification is relatively large.

The content is as follows:

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);

                 }
            });
        })
    })

upload effect

1. Display menu list

2. Click to upload the song

3. Upload completed

4. View the saved file

Increase database operations

At present, only the file upload function is implemented, and the file needs to be verified and the corresponding song information is added to the database, so that the playlist can display and play the song.

Modify the validation storage method

Change the original insert_music method into two methods, one is responsible for verifying the song information, and the other is responsible for the storage operation; and modify the return format of the function.

as follows:

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': '上传成功'}

Modify the song loading method

Because the song loading function of the above method is used, it also needs to be modified accordingly, specifically: call the function of verifying song information in the loop, and determine whether to store the operation by judging the return value.

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('加载本地音乐成功!')

Upload songs into library

The purpose of modifying the song verification and warehousing method is to make the method universal, so that the uploaded file can be used directly, and a prompt message will be returned.

@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提交文件!'})

Note: The file obtained through request.FILES is the file object at this time. If you need to use file to obtain the file name for storage.

Music player version 2 source code

Link: Baidu Netdisk Please enter the extraction code

Extraction code: e5th

Summarize

Added a separate song file upload on the original basis, using the layui control to upload,

The backend verifies the song file, saves it locally and puts it into the library for processing.

Guess you like

Origin blog.csdn.net/json_ligege/article/details/131683324