1、项目介绍
本系统以 Python 为核心开发语言,基于 Flask 框架构建后端服务,采用 MySQL 数据库进行数据存储。前端页面通过 HTML、CSS、JavaScript 结合 Bootstrap 框架构建,具备响应式布局与良好的交互效果。
功能模块主要包括:
- 系统首页
- 热门歌手与热门歌曲展示
- 全部歌手浏览
- 歌曲搜索
- 热门歌曲排行榜
- 后台数据管理
Django 在线音乐播放网站(实际代码实现为 Flask)是基于 Web 框架开发的音乐服务平台,通过整合音乐资源库、用户管理体系、音乐播放器及社交互动功能,为用户提供完整的在线音乐服务。平台内置丰富的音乐库资源,支持用户通过搜索或分类浏览发现喜爱的音乐。用户可注册登录并将喜欢的音乐保存至个人收藏夹,与其他用户分享音乐内容。网站配备功能完善的音乐播放器,支持播放、暂停、音量调节、歌曲切换等操作,用户还可创建个性化播放列表定制播放顺序。社交功能方面,用户可以关注其他音乐爱好者,查看其收藏的音乐和播放列表,并对分享的音乐进行评论和点赞,实现与其他用户的互动交流。
2、项目界面
(1)系统首页 该页面为在线音乐网首页,包含发现音乐、我的音乐、推荐、排行榜等主导航,以及曲风、歌手分类筛选模块,下方展示热门歌手和热门歌曲列表,右侧设有音乐播放控件,整体提供音乐浏览与播放入口功能。

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

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

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

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

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

3、项目说明
一、技术栈简要说明 本系统采用 Python 作为核心开发语言,基于 Flask 框架搭建后端架构,使用 MySQL 数据库进行数据存储管理。前端页面通过 HTML、CSS、JavaScript 结合 Bootstrap 框架构建,具备响应式布局与良好的交互效果,确保页面在不同设备上的适配性与操作流畅度。
二、功能模块详细介绍
- 系统首页:顶部设有发现音乐、我的音乐、推荐、排行榜等主导航模块。页面主体包含曲风和歌手分类筛选功能,便于用户按类别浏览音乐内容。下方展示热门歌手和热门歌曲列表,呈现当前平台热度较高的音乐资源。右侧集成音乐播放控件,提供基本的播放入口,整体界面实现音乐浏览与播放的一体化操作体验。
- 热门歌手与热门歌曲:顶部保留发现音乐、我的音乐、推荐、排行榜等导航模块。主体区域聚焦展示热门歌手和热门歌曲列表,通过直观的列表形式呈现平台内受欢迎的音乐内容。右侧设有音乐播放控件,用户可在浏览过程中随时试听感兴趣的歌曲,实现分类浏览与在线播放的便捷切换。
- 全部歌手:顶部包含发现音乐、我的音乐、推荐、排行榜等主导航。主体区域提供曲风筛选和歌手分类功能,支持用户按照不同维度查找喜欢的歌手。下方以列表形式展示歌手信息,并支持分页切换,方便用户浏览更多内容。右侧保留音乐播放控件,确保浏览过程中音乐播放不中断。
- 歌曲搜索:顶部设有发现音乐、我的音乐、推荐、排行榜等导航。左侧区域集成曲风、歌手分类导航以及搜索框,用户可输入关键词查找目标歌曲。主体区域展示搜索结果列表,包含歌曲名称、歌手、分类及播放次数等信息。底部集成音乐播放进度控制功能,支持播放进度调节,提供完整的搜索试听体验。
- 热门歌曲排行榜:顶部包含发现音乐、我的音乐、推荐、排行榜等导航模块。左侧设有曲风和歌手分类,方便用户按类别筛选榜单内容。主体区域展示热门歌手和歌曲 TOP30 榜单,以排行榜形式呈现平台热度最高的音乐内容,帮助用户发现优质音乐。右侧提供音乐播放控件入口,用户可快速试听榜单中的热门歌曲。
- 后台数据管理:管理员专属的后台管理界面,顶部包含发现音乐、我的音乐、推荐、排行榜及后台管理导航。左侧设有曲风和歌手分类,便于管理时快速定位相关内容。主体区域提供新增歌曲功能入口,管理员可上传新音乐并填写相关信息。下方以表格形式展示现有歌曲列表,包含歌曲名称、歌手、类型及操作按钮,支持对歌曲进行修改和删除维护,页面底部设有分页功能,方便管理大量数据,实现音乐资源的全流程维护。
三、项目总结 本系统是基于 Web 框架开发的在线音乐播放平台,通过整合音乐资源库、用户管理体系、音乐播放器及后台管理功能,构建了完整的音乐服务体系。前端采用 HTML、CSS、JavaScript 结合 Bootstrap 实现响应式界面,后端由 Python 处理业务逻辑与数据流转,MySQL 数据库保障数据存储安全。平台支持用户通过搜索和分类浏览发现音乐,可浏览热门歌手与歌曲榜单,内置播放器提供便捷的在线试听体验。后台管理模块支持对歌曲进行新增、修改和删除操作,保障平台内容持续更新。整体而言,该系统为用户提供了音乐发现、试听与管理的综合服务,满足了音乐爱好者的多元化需求。
4、核心代码
路由控制与视图函数是项目的核心部分,以下是关键逻辑的实现示例。
# _*_ coding: utf-8 _*
from app import 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.get('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
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)
# 写入到 user 表
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 = Collect.query.filter_by(
user_id=int(user_id), song_id=int(song_id)).count()
res = {}
# 已收藏
if collect == 1:
res['status'] = 0
res['message'] = '已经收藏'
# 未收藏进行收藏
if collect == 0:
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)

