跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Python大前端算法

Python 云音乐播放平台 Flask Bootstrap 管理系统

Python 云音乐播放平台基于 Flask 框架与 MySQL 数据库构建,前端采用 HTML CSS JavaScript 结合 Bootstrap 实现响应式布局。系统提供首页展示、热门歌曲排行、歌手浏览、搜索及后台管理功能。用户支持注册登录、收藏歌曲、在线播放及个性化列表定制。管理员可维护歌手信息与歌曲资源,包括上传、编辑、删除操作。整体架构满足音乐发现与管理的一站式服务需求。

ArchDesign发布于 2026/3/27更新于 2026/6/920 浏览
Python 云音乐播放平台 Flask Bootstrap 管理系统

1、项目介绍

技术栈 系统采用 Python 为核心开发语言,基于 Flask 框架完成后端架构搭建,使用 MySQL 数据库进行数据存储管理。前端页面通过 HTML、CSS、JavaScript 结合 Bootstrap 框架构建,具备响应式布局与良好的交互效果。

功能模块

  • 系统首页
  • 热门歌手与热门歌曲
  • 全部歌手浏览
  • 歌曲搜索
  • 热门歌曲排行榜
  • 后台数据管理

项目介绍 Flask 在线音乐播放网站是基于 Flask 框架开发的音乐服务平台,通过整合音乐资源库、用户管理体系、音乐播放器及社交互动功能,为用户提供完整的在线音乐服务。平台内置丰富的音乐库资源,支持用户通过搜索或分类浏览发现喜爱的音乐。用户可注册登录并将喜欢的音乐保存至个人收藏夹,与其他用户分享音乐内容。网站配备功能完善的音乐播放器,支持播放、暂停、音量调节、歌曲切换等操作,用户还可创建个性化播放列表定制播放顺序。社交功能方面,用户可以关注其他音乐爱好者,查看其收藏的音乐和播放列表,并对分享的音乐进行评论和点赞,实现与其他用户的互动交流。该平台为用户提供了音乐收听、发现、管理与社交的一站式服务体验。

2、项目界面

(1)系统首页 该页面为在线音乐网首页,包含发现音乐、我的音乐、推荐、排行榜等主导航,以及曲风、歌手分类筛选模块,下方展示热门歌手和热门歌曲列表,右侧设有音乐播放控件,整体提供音乐浏览与播放入口功能。

在这里插入图片描述

(2)热门歌手、热门歌曲 该页面为在线音乐网首页,顶部设有发现音乐、我的音乐、推荐、排行榜等导航模块,主体区域展示热门歌手和热门歌曲列表,右侧包含音乐播放控件,提供音乐分类浏览与在线播放入口功能。

在这里插入图片描述

(3)全部歌手 该页面为在线音乐网的歌手浏览页面,顶部包含发现音乐、我的音乐、推荐、排行榜等导航,主体区域提供曲风筛选和歌手分类功能,下方展示歌手列表并支持分页切换,右侧设有音乐播放控件。

在这里插入图片描述

(4)歌曲搜索 该页面为在线音乐网的搜索与播放页面,顶部包含发现音乐、我的音乐、推荐、排行榜等导航,左侧设有曲风、歌手分类及搜索框,主体区域展示搜索结果列表并显示歌曲信息,底部集成音乐播放进度控制功能。

在这里插入图片描述

(5)热门歌曲排行榜 该页面为在线音乐网的推荐页面,顶部包含发现音乐、我的音乐、推荐、排行榜等导航,左侧设有曲风、歌手分类,主体区域展示热门歌手和歌曲 TOP30 榜单,右侧提供音乐播放控件入口。

在这里插入图片描述

(6)后台数据管理 该页面为在线音乐网的后台管理界面,顶部包含发现音乐、我的音乐、推荐、排行榜及后台管理导航,左侧设有曲风、歌手分类,主体区域提供新增歌曲功能及歌曲列表管理,支持对歌曲进行修改和删除操作。

在这里插入图片描述

3、项目说明

一、技术栈简要说明 本系统采用 Python 作为核心开发语言,基于 Flask 框架完成后端架构搭建,使用 MySQL 数据库进行数据存储管理。前端页面通过 HTML、CSS、JavaScript 结合 Bootstrap 框架构建,具备响应式布局与良好的交互效果,确保页面在不同设备上的适配性与操作流畅度。

二、功能模块详细介绍 · 系统首页 该页面为在线音乐网首页,顶部设有发现音乐、我的音乐、推荐、排行榜等主导航模块。页面主体包含曲风和歌手分类筛选功能,便于用户按类别浏览音乐内容。下方展示热门歌手和热门歌曲列表,呈现当前平台热度较高的音乐资源。右侧集成音乐播放控件,提供基本的播放入口,整体界面实现音乐浏览与播放的一体化操作体验。

· 热门歌手与热门歌曲 该页面同样为首页的重要组成部分,顶部保留发现音乐、我的音乐、推荐、排行榜等导航模块。主体区域聚焦展示热门歌手和热门歌曲列表,通过直观的列表形式呈现平台内受欢迎的音乐内容。右侧设有音乐播放控件,用户可在浏览过程中随时试听感兴趣的歌曲,实现分类浏览与在线播放的便捷切换。

· 全部歌手 该页面为歌手浏览专属页面,顶部包含发现音乐、我的音乐、推荐、排行榜等主导航。主体区域提供曲风筛选和歌手分类功能,支持用户按照不同维度查找喜欢的歌手。下方以列表形式展示歌手信息,并支持分页切换,方便用户浏览更多内容。右侧保留音乐播放控件,确保浏览过程中音乐播放不中断。

· 歌曲搜索 该页面为搜索与播放综合页面,顶部设有发现音乐、我的音乐、推荐、排行榜等导航。左侧区域集成曲风、歌手分类导航以及搜索框,用户可输入关键词查找目标歌曲。主体区域展示搜索结果列表,包含歌曲名称、歌手、分类及播放次数等信息。底部集成音乐播放进度控制功能,支持播放进度调节,提供完整的搜索试听体验。

· 热门歌曲排行榜 该页面为推荐与排行榜页面,顶部包含发现音乐、我的音乐、推荐、排行榜等导航模块。左侧设有曲风和歌手分类,方便用户按类别筛选榜单内容。主体区域展示热门歌手和歌曲 TOP30 榜单,以排行榜形式呈现平台热度最高的音乐内容,帮助用户发现优质音乐。右侧提供音乐播放控件入口,用户可快速试听榜单中的热门歌曲。

· 后台数据管理 该页面为管理员专属的后台管理界面,顶部包含发现音乐、我的音乐、推荐、排行榜及后台管理导航。左侧设有曲风和歌手分类,便于管理时快速定位相关内容。主体区域提供新增歌曲功能入口,管理员可上传新音乐并填写相关信息。下方以表格形式展示现有歌曲列表,包含歌曲名称、歌手、类型及操作按钮,支持对歌曲进行修改和删除维护,页面底部设有分页功能,方便管理大量数据,实现音乐资源的全流程维护。

三、项目总结 本系统是基于 Flask 框架开发的在线音乐播放平台,通过整合音乐资源库、用户管理、音乐播放器及后台管理功能,构建了完整的音乐服务体系。前端采用 HTML、CSS、JavaScript 结合 Bootstrap 实现响应式界面,后端由 Flask 处理业务逻辑与数据流转,MySQL 数据库保障数据存储安全。平台支持用户通过搜索和分类浏览发现音乐,可浏览热门歌手与歌曲榜单,内置播放器提供便捷的在线试听体验。后台管理模块支持对歌曲进行新增、修改和删除操作,保障平台内容持续更新。整体而言,该系统为用户提供了音乐发现、试听与管理的综合服务,满足了音乐爱好者的多元化需求。

4、核心代码

# _*_ coding: utf-8 _*
from app import home, db
from app.home.forms import LoginForm, RegisterForm, SuggetionForm
from app.models import User, Artist, Song, Collect
from flask import render_template, url_for, redirect, flash, session, request, jsonify
from functools import wraps
import time
import os

base = os.path.dirname(__file__)
song_path = base + '/../static/song/'
img_path = base + '/../static/artist/'

def admin_login(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session['username'] != 'admin':
            return redirect(url_for("home.index"))
        return f(*args, **kwargs)
    return decorated_function

def user_login(f):
    """ 登录装饰器 """
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if "user_id" not in session:
            return "<script>alert('请先登录');history.go(-1)</script>"
        return f(*args, **kwargs)
    return decorated_function

@home.route("/contentFrame")
def contentFrame():
    """ 主页面 """
    hot_artist = Artist.query.filter_by(isHot=1).limit(12).all()
    hot_song = Song.query.order_by(Song.hits.desc()).limit(10).all()
    return render_template('home/contentFrame.html', hot_artist=hot_artist, hot_song=hot_song)

@home.route("/")
def index():
    """ 首页 """
    return render_template('home/index.html')

@home.route("/login/", methods=["GET", "POST"])
def login():
    """ 登录 """
    if request.method == 'POST':
        username = request.form.get("username")
        pwd = request.form.get("pwd")
        user = User.query.filter_by(username=username).first()
        res = {}
        if not user:
            res['status'] = -1
            res['message'] = '用户名不存在'
            return jsonify(res)
        if not user.check_pwd(pwd):
            res['status'] = -2
            res['message'] = '用户名和密码不匹配'
            return jsonify(res)
        session["user_id"] = user.id
        session["username"] = user.username
        res['status'] = 1
        res['message'] = '登录成功'
        return jsonify(res)
    return render_template("home/login.html")

@home.route("/register/", methods=["GET", "POST"])
def register():
    """ 注册功能 """
    if request.method == "POST":
        username = request.form.get("username")
        pwd = request.form.get("pwd")
        user = User.query.filter_by(username=username).first()
        if user:
            res = {}
            res['status'] = -2
            res['message'] = '该用户已存在'
            return jsonify(res)
        try:
            user = User(username=username, pwd=pwd)
            db.session.add(user)
            db.session.commit()
            res = {}
            res['status'] = 1
            res['message'] = '注册成功'
        except:
            res = {}
            res['status'] = -1
            res['message'] = '注册失败'
        return jsonify(res)
    return render_template("home/register.html")

@home.route("/logout/")
def logout():
    """ 退出登录 """
    session.pop("user_id", None)
    session.pop("username", None)
    return redirect(url_for('home.index'))

@home.route("/artist/<int:id>")
def artist(id=None):
    """ 歌手页 """
    song = Song.query.join(Artist, Song.singer == Artist.artistName).filter(Artist.id==id).all()
    hot_artist = Artist.query.limit(6).all()
    return render_template('home/artist.html', song=song, hot_artist=hot_artist)

@home.route("/play_song")
def playSong():
    """ 获取播放路径 """
    song_id = request.args.get("id", "")
    song = Song.query.filter_by(id=int(song_id)).first()
    res = {}
    res['status'] = 1
    res['path'] = song.fileURL
    return jsonify(res)

@home.route("/toplist")
def toplist():
    top_song = Song.query.order_by(Song.hits.desc()).limit(30).all()
    hot_artist = Artist.query.limit(6).all()
    return render_template('home/toplist.html', top_song=top_song, hot_artist=hot_artist)

@home.route('/style_list')
def styleList():
    type_val = request.args.get('type', 0, type=int)
    page = request.args.get('page', type=int)
    if type_val:
        page_data = Song.query.filter_by(style=type_val).order_by(Song.hits.desc()).paginate(page=page, per_page=10)
    else:
        page_data = Song.query.order_by(Song.hits.desc()).paginate(page=page, per_page=10)
    return render_template('home/styleList.html', page_data=page_data, type=type_val)

@home.route('/artist_list')
def artistList():
    ''' 歌手列表 '''
    type_val = request.args.get('type', 0, type=int)
    page = request.args.get('page', type=int)
    if type_val:
        page_data = Artist.query.filter_by(style=type_val).paginate(page=page, per_page=10)
    else:
        page_data = Artist.query.paginate(page=page, per_page=10)
    return render_template('home/artistList.html', page_data=page_data, type=type_val)

@home.route('/search')
def search():
    keyword = request.args.get('keyword')
    page = request.args.get('page', type=int)
    if keyword:
        keyword = keyword.strip()
        page_data = Song.query.filter(Song.songName.like('%' + keyword + '%')).order_by(Song.hits.desc()).paginate(page=page, per_page=10)
    else:
        page_data = Song.query.order_by(Song.hits.desc()).paginate(page=page, per_page=10)
    return render_template('home/search.html', keyword=keyword, page_data=page_data)

@home.route('/modify_password', methods=['GET', 'POST'])
def modifyPassword():
    if request.method == 'POST':
        old_pwd = request.form.get("old_pwd")
        new_pwd = request.form.get("new_pwd")
        user = User.query.filter_by(id=session['user_id']).first()
        res = {}
        if not user.check_pwd(old_pwd):
            res['status'] = -1
            res['message'] = '原始密码错误'
            return jsonify(res)
        try:
            user.pwd = new_pwd
            db.session.add(user)
            db.session.commit()
            res['status'] = 1
            res['message'] = '密码修改成功'
            return jsonify(res)
        except:
            res['status'] = -2
            res['message'] = '密码修改错误'
            return jsonify(res)
    return render_template("home/modifyPassword.html")

@home.route("/collect")
@user_login
def collect():
    """ 收藏歌曲 """
    song_id = request.args.get("id", "")
    user_id = session['user_id']
    collect_count = Collect.query.filter_by(user_id=int(user_id), song_id=int(song_id)).count()
    res = {}
    if collect_count == 1:
        res['status'] = 0
        res['message'] = '已经收藏'
    else:
        collect_obj = Collect(user_id=int(user_id), song_id=int(song_id))
        db.session.add(collect_obj)
        db.session.commit()
        res['status'] = 1
        res['message'] = '收藏成功'
    return jsonify(res)

@home.route("/collect_list")
@user_login
def collectList():
    page = request.args.get('page', type=int)
    page_data = Collect.query.paginate(page=page, per_page=10)
    return render_template('home/collectList.html', page_data=page_data)

@home.route("/manage_artist_list")
@admin_login
def manageArtist():
    ''' 后台管理 '''
    page = request.args.get('page', type=int)
    page_data = Artist.query.paginate(page=page, per_page=10)
    return render_template('home/manageArtist.html', page_data=page_data)

@home.route("/manage_artist_add", methods=["GET", "POST"])
@admin_login
def manageArtistAdd():
    ''' 新增歌手 '''
    if request.method == "POST":
        artistName = request.form.get("artistName")
        style = request.form.get("style")
        imgURL = request.form.get("imgURL")
        isHot = request.form.get("isHot")
        artist = Artist.query.filter_by(artistName=artistName).first()
        if artist:
            res = {}
            res['status'] = -2
            res['message'] = '该歌手已存在'
            return jsonify(res)
        try:
            artist = Artist(artistName=artistName, style=int(style), imgURL=imgURL, isHot=int(isHot))
            db.session.add(artist)
            db.session.commit()
            res = {}
            res['status'] = 1
            res['message'] = '添加成功'
        except:
            res = {}
            res['status'] = -1
            res['message'] = '添加失败'
        return jsonify(res)
    return render_template('home/manageArtistAdd.html')

@home.route("/manage_artist_edit", methods=["GET", "POST"])
@admin_login
def manageArtistEdit():
    ''' 编辑歌手 '''
    id_val = request.values['id']
    artist = Artist.query.filter_by(id=id_val).first()
    if request.method == "POST":
        artistName = request.form.get("artistName")
        style = request.form.get("style")
        isHot = request.form.get("isHot")
        try:
            artist.artistName = artistName
            artist.style = int(style)
            artist.isHot = int(isHot)
            db.session.add(artist)
            db.session.commit()
            res = {}
            res['status'] = 1
            res['message'] = '保存成功'
        except:
            res = {}
            res['status'] = -1
            res['message'] = '保存失败'
        return jsonify(res)
    return render_template('home/manageArtistEdit.html', artist=artist)

@home.route("/manage_artist_del")
@admin_login
def manageArtistDel():
    ''' 删除歌手 '''
    id_val = request.args.get('id')
    try:
        artist = Artist.query.get_or_404(int(id_val))
        db.session.delete(artist)
        db.session.commit()
        res = {}
        res['status'] = 1
        res['message'] = '删除成功'
    except:
        res = {}
        res['status'] = -1
        res['message'] = '删除失败'
    return jsonify(res)

@home.route("/manage_song_list")
@admin_login
def manageSong():
    ''' 歌曲管理 '''
    page = request.args.get('page', type=int)
    page_data = Song.query.paginate(page=page, per_page=10)
    return render_template('home/manageSong.html', page_data=page_data)

@home.route("/manage_song_add", methods=["GET", "POST"])
@admin_login
def manageSongAdd():
    ''' 新增歌曲 '''
    if request.method == "POST":
        songName = request.form.get("songName")
        singer = request.form.get("singer")
        style = request.form.get("style")
        fileURL = request.form.get("fileURL")
        song = Song.query.filter_by(songName=songName).first()
        if song:
            res = {}
            res['status'] = -2
            res['message'] = '该歌曲已存在'
            return jsonify(res)
        try:
            song = Song(songName=songName, singer=singer, style=1, fileURL=fileURL)
            db.session.add(song)
            db.session.commit()
            res = {}
            res['status'] = 1
            res['message'] = '添加成功'
        except:
            res = {}
            res['status'] = -1
            res['message'] = '添加失败'
        return jsonify(res)
    return render_template('home/manageSongAdd.html')

@home.route("/manage_song_edit", methods=["GET", "POST"])
@admin_login
def manageSongEdit():
    ''' 编辑歌曲 '''
    id_val = request.values['id']
    song = Song.query.filter_by(id=id_val).first()
    if request.method == "POST":
        songName = request.form.get("songName")
        singer = request.form.get("singer")
        style = request.form.get("style")
        try:
            song.songName = songName
            song.singer = singer
            song.style = int(style)
            db.session.add(song)
            db.session.commit()
            res = {}
            res['status'] = 1
            res['message'] = '保存成功'
        except:
            res = {}
            res['status'] = -1
            res['message'] = '保存失败'
        return jsonify(res)
    return render_template('home/manageSongEdit.html', song=song)

@home.route("/manage_song_del")
@admin_login
def manageSongDel():
    ''' 删除歌曲 '''
    id_val = request.args.get('id')
    try:
        song = Song.query.get_or_404(int(id_val))
        db.session.delete(song)
        db.session.commit()
        res = {}
        res['status'] = 1
        res['message'] = '删除成功'
    except:
        res = {}
        res['status'] = -1
        res['message'] = '删除失败'
    return jsonify(res)

@home.route("/upload", methods=["POST"])
@admin_login
def upload():
    """接受前端传送过来的文件"""
    file_obj = request.files.get("mp3")
    if file_obj is None:
        return "文件上传为空"
    path = str(int(time.time())) + ".mp3"
    file_obj.save(os.path.join(song_path, path))
    res = {}
    res['status'] = 1
    res['path'] = path
    return jsonify(res)

@home.route("/upload/img", methods=["POST"])
@admin_login
def uploadImg():
    """接受前端传送过来的文件"""
    file_obj = request.files.get("img")
    if file_obj is None:
        return "文件上传为空"
    path = str(int(time.time())) + ".jpg"
    file_obj.save(os.path.join(img_path, path))
    res = {}
    res['status'] = 1
    res['path'] = path
    return jsonify(res)

@home.route('/addHit')
def addHit():
    ''' 点击量加 1 '''
    id_val = request.args.get('id')
    song = Song.query.get_or_404(int(id_val))
    if not song:
        res = {}
        res['status'] = -1
        res['message'] = '歌曲不存在'
    else:
        song.hits += 1
        db.session.add(song)
        db.session.commit()
        res = {}
        res['status'] = 1
        res['message'] = '播放次数加 1'
    return jsonify(res)

目录

  1. 1、项目介绍
  2. 2、项目界面
  3. 3、项目说明
  4. 4、核心代码
  5. _ coding: utf-8
  • 💰 8折买阿里云服务器限时8折了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 🤖 一键搭建Deepseek满血版了解详情
  • 一键打造专属AI 智能体了解详情
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • MySQL 内置函数详解:聚合、日期、字符串及数学运算
  • FLUX.1-dev FP8 量化模型部署与优化指南
  • 无人机光伏缺陷检测数据集:红外与可见光双模态配对数据及 YOLO 融合方案
  • 使用 NCC 和 PKG 将 Node.js 项目打包为跨平台可执行文件
  • 黑客零基础入门教程:从零开始学习网络安全技术
  • 基于 MCP 协议的图片素描风格转换工具使用指南
  • React K 线图组件:开箱即用,支持多周期与指标计算
  • MCP Python SDK 协议层实现机制详解
  • 转行 AI 产品经理:行业趋势与核心面试指南
  • 零代码上手!用 Rokid 灵珠平台,5 步搭建专属旅游 AR 智能体
  • 节点小宝 4.0 macOS 客户端正式发布
  • GitHub 学生开发者包认证实操指南
  • VSCode AI Copilot 配置指南:提升补全准确率的实战技巧
  • Spring 事务及其传播机制详解
  • CoppeliaSim 分拣机器人与寻迹小车仿真:码垛、颜色识别及随机物块处理
  • Cursor 中配置与使用 MCP 服务指南
  • DeepSeek-R1-Distill-Llama-8B:80 亿参数推理模型开源
  • ToDesk 发布 ToClaw:AI 可直接操作电脑
  • Stable Diffusion 完整训练与推理流程详解(附伪代码)
  • GLM-4.7-Flash 实战:构建本地 Copilot 编程助手

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online