flask搭建在线音乐网系统(一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: flask搭建在线音乐网系统(一)

1.使用虚拟环境Virtualenv来创建项目

8657bda8e89d4b58aa4f8bef81f3a311.png 2. Flask框架介绍

Flask框架是一个用Python编写的轻量级Web应用程序框架,依赖于Werkzeug和Jinja2两个外部库。Werkzeug是一个WSGI工具包,用于接收和处理HTTP请求,匹配视图函数,支持Cookie和会话管理,交互式调试等功能。Jinja2是一个模板引擎,用于将响应结果渲染到模板文件,支持动态网页的呈现。Flask框架的核心构成简单,但具有很强的扩展性和兼容性,可以根据需要选择不同的数据库和其他功能扩展。Flask框架主要用于开发Web应用程序,例如网站或Web服务。

安装flask框架,使用以下代码,或者直接在pycharm设置的++下安装

pip install flask

3.创建Flask项目

在终端中进入要创建项目的目录,输入以下命令创建Flask项目:

mkdir Online-Music-main
cd Online-Music-main

4. 创建Flask app  

在Online-Music-main目录下创建一个Python文件,命名为app.py

# _*_ codding:utf-8 _*_
from app import create_app, db
from app.models import *
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
from flask import render_template
app = create_app('default')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
    return dict(app=app, db=db)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
@app.errorhandler(404)
def page_not_found(error):
    """
    404
    """
    return render_template("home/404.html"), 404
if __name__ == '__main__':
    manager.run()

5.配置config.py文件,连接数据库

# -*- coding=utf-8 -*-
import os
class Config:
    SECRET_KEY = 'mrsoft'
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    @staticmethod
    def init_app(app):
        '''初始化配置文件'''
        pass
# the config for development
class DevelopmentConfig(Config):
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456@127.0.0.1:3306/music'
    DEBUG = True
# define the config
config = {
    'default': DevelopmentConfig
}

6在添加models模型,

from . import db
# 用户表
class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer, primary_key=True)             # 编号
    username = db.Column(db.String(100))                     # 用户名
    pwd = db.Column(db.String(100))                          # 密码
    flag = db.Column(db.Boolean,default=0)                   # 用户标识,0:普通用户 1:管理员
    def __repr__(self):
        return '<User %r>' % self.name
    def check_pwd(self, pwd):
        """
        检测密码是否正确
        :param pwd: 密码
        :return: 返回布尔值
        """
        return self.pwd == pwd
# 歌手表
class Artist(db.Model):
    __tablename__ =  'artist'
    id = db.Column(db.Integer, primary_key=True)             # 编号
    artistName = db.Column(db.String(100))                    # 歌手名
    style = db.Column(db.Integer)                             # 歌手类型
    imgURL = db.Column(db.String(100))                        # 头像
    isHot = db.Column(db.Boolean,default=0)                   # 是否热门
# 歌曲表
class Song(db.Model):
    __tablename__ = 'song'
    id = db.Column(db.Integer, primary_key=True)              # 编号
    songName = db.Column(db.String(100))                      # 歌曲名称
    singer = db.Column(db.String(100))                        # 歌手名称
    fileURL = db.Column(db.String(100))                       # 歌曲图片
    hits = db.Column(db.Integer,default=0)                    # 点击量
    style = db.Column(db.Integer)                             # 歌曲类型 0:全部 1:华语 2:欧美 3:日语 4:韩语 5 其他
    collect = db.relationship('Collect', backref='song')      # 收藏外键关系关联
# 歌曲收藏
class Collect(db.Model):
    __tablename__ = "collect"
    id = db.Column(db.Integer, primary_key=True)              # 编号
    song_id = db.Column(db.Integer, db.ForeignKey('song.id')) # 所属歌曲
    user_id = db.Column(db.Integer)                           # 所属用户

7.写视图views.py,最后渲染前端网页实现界面

# _*_ coding: utf-8 _*_
from . import home
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 werkzeug.security import generate_password_hash
from functools import wraps
def admin_login(f):
    @wraps(f)
    def decorated_function(*args, **kwargs):
        if session['username'] != 'mr' :
            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):     # 调用check_pwd()方法,检测用户名密码是否匹配
            res['status'] = -2
            res['message'] = '用户名和密码不匹配'
            return jsonify(res)
        # 用户名和密码正确,写入session
        session["user_id"] = user.id  # 将user_id写入session, 后面用户判断用户是否登录
        session["username"] = user.username  # 将user_id写入session, 后面用户判断用户是否登录
        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 = User(
                username = username,  # 用户名
                pwd = generate_password_hash(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():
    """
    退出登录
    """
    # 重定向到home模块下的登录。
    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("/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 = request.args.get('type',0,type=int)
    page = request.args.get('page',type=int)  # 获取page参数值
    if type:
        page_data = Song.query.filter_by(style=type).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)  # 渲染模板
@home.route('/artist_list')
def artistList():
    '''
    歌手列表
    '''
    type = request.args.get('type',0,type=int)
    page = request.args.get('page',type=int)  # 获取page参数值
    if type:
        page_data = Artist.query.filter_by(style=type).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)  # 渲染模板
# 发现音乐
@home.route('/search')
def search():
    keyword = request.args.get('keyword')  # 获取关键字
    page = request.args.get('page', type=int)  # 获取page参数值
    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 = generate_password_hash(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", "")            # 接收传递的参数歌曲ID
    user_id   = session['user_id']                  # 获取当前用户的ID
    collect = Collect.query.filter_by(              # 根据用户ID和景区ID判断是否该收藏
        user_id =int(user_id),
        song_id=int(song_id)
    ).count()
    res = {}
    # 已收藏
    if collect == 1:
        res['status'] = 0
        res['message'] = '已经收藏'
    # 未收藏进行收藏
    if collect == 0:
        collect = Collect(
            user_id =int(user_id),
            song_id=int(song_id)
        )
        db.session.add(collect)  # 添加数据
        db.session.commit()      # 提交数据
        res['status'] = 1
        res['message'] = '收藏成功'
    return jsonify(res)     # 返回json数据
@home.route("/collect_list")
@user_login
def collectList():
    page = request.args.get('page',type=int)  # 获取page参数值
    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参数值
    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)
        # 写入到Artist表
        try:
            # 为Artist类属性赋值
            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 = request.values['id']      # POST和GET提交都可以获取ID
    artist = Artist.query.filter_by(id=id).first()  # 获取用户信息
    if request.method == "POST":   # 提交注册表单
        # 更改Artist表
        artistName = request.form.get("artistName")
        style = request.form.get("style")
        imgURL = request.form.get("imgURL")
        isHot = request.form.get("isHot")
        try:
            artist.artistName = artistName
            artist.style = int(style)
            artist.imgURL = imgURL
            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 = request.args.get('id')      # 获取ID
    try:
        artist = Artist.query.get_or_404(int(id))
        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参数值
    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)
        # 写入到Song表
        # 为Song类属性赋值
        try:
            # 为Song类属性赋值
            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 = request.values['id']      # POST和GET提交都可以获取ID
    song = Song.query.filter_by(id=id).first()  # 获取用户信息
    if request.method == "POST":   # 提交注册表单
        # 更改Song表
        songName = request.form.get("songName")
        singer = request.form.get("singer")
        style = request.form.get("style")
        fileURL = request.form.get("fileURL")
        try:
            song.songName = songName
            song.singer = singer
            song.style = int(style)
            song.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/manageSongEdit.html',song=song)
@home.route("/manage_song_del")
@admin_login
def manageSongDel():
    '''
    删除歌曲
    '''
    id = request.args.get('id')      # 获取ID
    try:
        song = Song.query.get_or_404(int(id))
        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('/addHit')
def addHit():
    '''
    点击量加1
    '''
    id = request.args.get('id')
    song = Song.query.get_or_404(int(id))
    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)

8.templates/index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf8">
    <title>小林云音乐</title>
    <link href="{{ url_for('static',filename='css/core.css')}}" rel="stylesheet">
    <link href="{{ url_for('static',filename='css/pt_frame.css')}}" rel="stylesheet">
  <link href="{{ url_for('static',filename='js/toolTip/tooltip.css')}}" rel="stylesheet">
  <script type="text/javascript" src="{{url_for('static',filename='js/toolTip/tooltip.js')}}"></script>
   <script type="text/javascript" src="{{url_for('static',filename='js/jquery-2.2.0.min.js')}}"></script>
    <style>html, body {
        overflow: hidden;
    }</style>
    <script>if (top != self)top.location = self.location;</script>
</head>
<body class="auto-1469062573613-parent auto-1469062573612-parent">
<div id="g-topbar" class="g-topbar">
    <div class="m-top">
        <div class="wrap">
            <h1 class="logo"><a hidefocus="true" target="contentFrame" href="{{url_for('home.index')}}">甜橙云音乐</a></h1>
            <ul class="m-nav j-tflag">
                <li class="fst">
                    <span><a hidefocus="true" target="contentFrame" href="{{url_for('home.search')}}" data-module="discover" class="z-slt"><em>发现音乐</em></a></span>
                </li>
                <li>
                    <span><a target="contentFrame" href="{{url_for('home.collectList')}}"><em>我的音乐</em><sub class="cor">&nbsp;</sub></a></span>
                </li>
            </ul>
      {% if session['username'] %}
            <div class="m-tophead f-pr j-tflag" >
        <a onmouseover="tooltip.pop(this, '#textContent',{position:1, offsetX:0,  effect:'slide'})"  class="tooltip" style="color:#1C2021">您好,{{ session['username']}}</a>
            </div>
      <div style="display: none">
        <div id="textContent" style="width: 75px; height: 45px;color:black">
          {% if session['username'] == 'mr' %}
          <a target="contentFrame" href="{{url_for('home.manageArtist')}}">后台管理</a>
          {% else %}
          <a target="contentFrame" href="{{url_for('home.modifyPassword')}}">修改密码</a>
          {% endif %}
          <br />
          <a id="blogUrl" href="{{url_for('home.logout')}}">退出</a>
        </div>
      </div>
      {% else %}
      <div class="m-tophead f-pr j-tflag">
        <a id="login" class="name f-thide f-fl f-tdn" style="color:#1C2021">登录</a>
        <a id="register" class="name f-thide f-fl f-tdn" style="color:#1C2021">注册</a>
      </div>
      {% endif %}
    </div>
    </div>
    <div class="m-subnav m-subnav-up f-pr j-tflag f-hide">
        <div class="shadow">&nbsp;</div>
    </div>
    <div id="g_nav2" class="m-subnav j-tflag">
        <div class="wrap f-pr">
            <ul class="nav">
                <li><a hidefocus="true" target="contentFrame" href="{{url_for('home.index')}}" data-module="discover"
                       class="z-slt menuTab"><em>推荐</em></a></li>
                <li><a hidefocus="true" target="contentFrame"  href="{{url_for('home.toplist')}}" data-module="toplist"
                       class="menuTab"><em>排行榜</em></a></li>
                <li><a hidefocus="true" target="contentFrame"  href="{{url_for('home.styleList')}}" data-module="playlist"
             class="menuTab"><em>曲风</em></a>
                </li>
                <li><a hidefocus="true" target="contentFrame"  href="{{url_for('home.artistList')}}" data-module="artist"
                       class="menuTab"><em>歌手</em></a>
        </li>
            </ul>
        </div>
    </div>
</div>
<script>
$(".menuTab").bind("click", function(obj){
  $('.menuTab').removeClass("z-slt");
  obj.currentTarget.className='z-slt menuTab';
});
</script>
<iframe name="contentFrame" id="g_iframe" class="g-iframe" scrolling="auto" frameborder="0"
        src="{{ url_for('home.contentFrame') }}">
</iframe>
<link href="{{url_for('static',filename='css/jplayer.blue.monday.min.css')}}" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="{{url_for('static',filename='js/jplayer/jquery.jplayer.min.js')}}"></script>
<script>
// 定义播放音乐的方法
function playMusic(name, id) {
   $("#jquery_jplayer").jPlayer( "destroy" );           // 销毁正在播放的音乐
   $("#jquery_jplayer").jPlayer({           // 播放音乐
    ready: function(event) {            // 准备音频
      $(this).jPlayer("setMedia", {
        title: name,              // 设置音乐标题
        mp3: "static/images/song/53.mp3"    // 设置播放音乐
      }).jPlayer( "play" );           // 开始播放
    },
    swfPath: "dist/jplayer/jquery.jplayer.swf",     // IE8下的兼容播放
    supplied: "mp3",                // 音乐格式为mp3
    wmode: "window",                // 播放模式“window”
    useStateClassSkin: true,            // 设置默认样式
    autoBlur: false,                // 不支持模糊
    smoothPlayBar: true,              // 支持图标
    keyEnabled: true,               // 支持键盘
    remainingDuration: true,            // 支持动画
    toggleDuration: true              // 支持进度条
  });
}
// 添加收藏
function addShow(id){
  var username= "{{session['username']}}";
  if(username=="null" || username==""){
    layer.msg("收藏请先登录!",{icon:2,time:1000});
    return;
  }
  $.ajax({
    url: "{{url_for('home.collect')}}",
    type: "get",
    data: {
      id: id
    },
    success: function(res){
      if(res.status==1){
        layer.msg(res.message,{icon:1})
      }else{
        layer.msg(res.message,{icon:2})
      }
        }
     });
}
</script>
    <div id="demo" style="z-index: 999; position: fixed;right:0;left:0;bottom:0;width:100%;">
      <div id="jquery_jplayer" class="jp-jplayer">
      </div>
      <div id="jp_container_1" class="jp-audio" role="application"
        aria-label="media player">
        <div class="jp-type-single">
          <div class="jp-details">
            <div class="jp-title" aria-label="title">
              暂无播放音乐
            </div>
          </div>
          <div class="jp-gui jp-interface" style="margin-left:30% " >
            <div class="jp-controls">
              <button class="jp-play" role="button" tabindex="0">
                play
              </button>
            </div>
            <div class="jp-progress">
              <div class="jp-seek-bar">
                <div class="jp-play-bar"></div>
              </div>
            </div>
            <div class="jp-volume-controls">
              <button class="jp-mute" role="button" tabindex="0">
                mute
              </button>
              <button class="jp-volume-max" role="button" tabindex="0">
                max volume
              </button>
              <div class="jp-volume-bar">
                <div class="jp-volume-bar-value"></div>
              </div>
              <div class="jp-duration" role="timer" aria-label="duration">
                &nbsp;
              </div>
              <div class="jp-time-holder">
                <div class="jp-duration" role="timer" aria-label="duration">
                  &nbsp;
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
<script type="text/javascript" src="{{url_for('static',filename='js/layer/layer.js')}}"></script>
<script>
// 登录弹窗
$("#login").click(function () {
  layer.open({
    type: 2,
    title: '登录',
    shadeClose: true,
    shade: 0.4,
    area: ['700px', '550px'],
    content: ['/login','no'] //iframe的url
  });
});
// 注册弹窗
$("#register").click(function () {
  layer.open({
    type: 2,
    title: '注册',
    shadeClose: true,
    shade: 0.4,
    area: ['700px', '550px'],
    content: ['/register','no'] //iframe的url
  });
})
</script>
</body>
</html>

templates/login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link href="{{ url_for('static',filename='css/core.css')}}" rel="stylesheet">
    <link href="{{ url_for('static',filename='css/pt_frame.css')}}" rel="stylesheet">
    <link href="{{ url_for('static',filename='css/login.css')}}" rel="stylesheet">
    <script type="text/javascript" src="{{url_for('static',filename='js/jquery-2.2.0.min.js')}}"></script>
     <script type="text/javascript" src="{{url_for('static',filename='js/layer/layer.js')}}"></script>
</head>
<body>
<div id="loginHtml">
<div class="left">
</div>
<div class="right" style="background: #f0f3f9 url('../../static/image/login-rightBg.jpg') no-repeat;">
<div class="respond">
    <form  method="post" action="{{url_for('home.login')}}"  id="commentform" onsubmit="return false">
        <div class="comment-login"></div>
        <div class="comment-login" style="font-size:16px;margin-top:-40px">
        <ul style="margin-top:100px">
        <li class="form-inline">
        <label><strong>用户名:</strong></label>
        <input type="text" name="username" id="username" value="" tabindex="1" aria-required="true">
        </li>
        <li class="form-inline">
        <label><strong>密&nbsp&nbsp&nbsp&nbsp码:</strong></label>
        <input type="password" name="pwd" id="pwd" value="" tabindex="2" aria-required="true">
        </li>
        </ul>
        </div>
        <div class="comment-login">
            <input name="submit" type="submit" id="login"  class="submitButton" tabindex="5"  value="登录">
        </div>
    </form>
</div>
</div>
</div>
<script>
    $('#login').click(function(){
        var username = $('#username').val()
        var pwd = $('#pwd').val()
        if(username == ''){
            layer.msg('请输入用户名',{icon:2,time:1000});
            return false;
        }
         if(pwd == ''){
            layer.msg('请输入密码',{icon:2,time:1000});
            return false;
         }
        $.ajax({                                    // 使用Ajax异步提交
            url: "{{ url_for('home.login') }}",   // 提交到的URL
            type: "POST",                            // 提交方式为GET
            data:{username: username,pwd:pwd},       // 传递参数
            dataType: "json",                       // 数据类型为json
            success: function (res) {               // 操作成功后执行逻辑
                if (res.status == 1) {
                    layer.msg(res.message,{icon:1,time:2000},function(){
                        window.parent.location.reload();                        // 从新加载父页面
                        var index = parent.layer.getFrameIndex(window.name);    // 获取当frame标识
                        parent.layer.close(index);                              // 关闭当前页
                    });
                } else {
                    layer.msg(res.message,{icon:2,time:2000});   // 提示已收藏
                }
            }
        })
    })
</script>
</body>
</html>

最后运行python app.py runserver

因为前端网页页面有点多,需要源代码可以私信博主

摘要:

大数据时代下,数据不断增长,为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在音乐系统的要求下,开发一款整体式结构的音乐网系统,将顺应时代的发展,能够实现对需求变化的快速响应、系统稳定性的保障,能保证平台可持续、规模化发展的需求。

本系统的前端界面涉及技术主要有python、HTML等等,通过这些技术可以实现前端页面的美观和动态效果使符合广大群众的审美观,后台主要使用的技术有python编程语言,MySQL数据库、Flask框架,Flask框架可以通过ORM映射,最后渲染出用户喜欢的页面,本系统介绍了整个应用系统的设计思路,本文对每个部分进行了分析,本文设计的是用前后端结合做出的音乐网系统,用户和管理员都能进行使用,用户可以通过查询找到自己喜欢的歌曲进行播放收藏,管理员登陆后可以新增歌手和歌曲,更合理地管理音乐网系统,也能快速上线新的流行歌曲,供用户进行收听。

关键词:

音乐网系统;Flask;ORM;数据库;前端。

目录

第1章 绪论

1.1研究背景与意义

1.2 开发现状

1.3  论文结构与章节安排

第2章 相关技术

2.1 Flask框架介绍

2.2 ORM技术概述

2.3本章小结

第3章 需求分析

3.1 系统初步调查

3.2 总体需求

3.3 开发平台

3.4 本章小结

第4章 系统概要设计

4.1 系统设计概述

4.2 系统用例图

4.3 系统流程图

4.4 系统功能分析

4.5 本章小结

第5章 数据库设计

5.1数据库结构设计

5.1.1数据库表

第6章 系统具体实现

6.1 项目基础框架搭建

6.2 系统功能模块实现

6.2.1 推荐功能模块实现

6.2.2 用户登录功能实现

6.2.3用户注册功能实现

6.2.4 歌曲播放功能实现

6.2.5歌曲查询实现

6.2.6 排行榜功能实现:

6.2.7曲风功能实现

6.2.8 歌手功能实现

6.3 管理员功能实现

6.3.1 歌手管理功能实现

6.3.2 歌曲管理功能实现

6.4 本章小结

第7章 系统测试

7.1系统测试方法介绍

7.2 系统功能测试

7.3系统测试结果

7.4 音乐网系统实现全过程

7.5 本章小结

第8章.总结

8.1工作总结

参考文献

致谢


  1. 1.绪论

1.1研究背景与意义

随着我国网民的增加,也促进了网络音乐产业的发展。在这个大环境下,网络音乐行业的竞争也越来越激烈,音乐通过网络这个媒介更多的进入人们的日常工作休闲。随着网络技术的日趋成熟和普及,各类网站都快速出现在互联网上,音乐网站是其中较为流行和热门的一种。从音乐网站上发展而来的网络音乐是一种全新的音乐模式,它突破传统音乐的制作方法和传播模式的局限,音乐网站是网络音乐的发展平台。过去,音乐网站的功能比较单一,现在随着互联网的高速发展,用户对音乐网站的需求也越来越高,音乐网站也出现了较多采用优越的开发工具(如Flask、JSP、Django、Javascript等)来开发音乐网站,本课题所研究音乐网站就是想自己听听歌,把自己喜欢的歌收藏起来,从而给个人带来方便。

对于在线音乐网站来说,用户下载次数和访问量是至关重要的,因此,在线音乐网必须为用户提供大量,全面的,而且是最新的音乐,这样才能吸引用户,网站要提供流行歌曲和排行靠前的音乐,还需要为用户提供收藏服务。

1.2 开发现状

我国在线音乐发展较早,开始于2002年百度上线MP3业务为用户免费提供音乐下载服务,紧接着酷狗、酷我和QQ音乐等主流平台相继成立,此时在线音乐仍处于起步阶段,市场乱象丛生,基本上处于无秩序发展阶段,09年文化部发布相关监管通知但收效甚微,导致我国在线音乐进入狂野生长阶段,盗版丛生,阻碍了在线音乐的健康发展,网易云音乐于此时成立,中国移动音乐行业的发展紧随互联网发展步伐,经过野蛮发展期、规范洗牌期而后步入了成熟稳定期,腾讯音乐集团和网易云音乐以“一超一强”形态攻占超过90%以上市场。随着用户的付费意愿提高、付费用户数不断增长,2017-2020年,中国移动音乐市场规模从66.3亿元增长到127.8亿元,年复

合增长率51.24%。随着政府加大国内音乐市场正版化、规范化力度和强度以及付费规模增长,市场规模增长可期。

1.3  论文结构与章节安排

本论文主要分为八个章节对课题进行论述,每个章节的内容如下所示:

绪论。主要讲述了对于当前音乐网的调研情况,介绍了此课题提出的背景和研究的意义,

相关介绍。介绍了此音乐网系统开发时所用的框架Flask和新型技术ORM作详细介绍。

需求分析。本章根据中国网数据得知,当前音乐网的发展趋势蓬勃发展,然后确定音乐网系统的总体需求,然后介绍开发音乐网所用到的开发工具做了详细概述。

系统概要设计。本章基于第三章的需求对音乐网管理系统作了全面的设计,首先设计了系统的总体架构,然后对音乐网管理系统的功能设计重点的作了介绍,接着对该套系统的数据库和ORM模型作了设计,最后系统的安全性作了分析。系统实现。按照系统的需求和设计说明书,实现了在线音乐网系统所有的功能模块。

数据库设计。介绍了在线音乐网数据库里面的数据表

第六章 系统具体实现。介绍了测试信息管理系统相关的理论知识;接着对音乐网系统从功能进行测试,保证系统的可用性、易用性和安全性。

第七章 系统测试。介绍了测试音乐网系统相关的理论知识;接着对在线音乐系统从功能进行测试,保证系统的可用性、易用性和安全性。

第八章 总结。对论文的主要工作进行了总结,分析本课题开发图书管理系统实现的功能和优势

第2章 相关技术

2.1 Flask框架介绍

Flask框架是一个用Python编写的轻量级Web应用程序框架,依赖于Werkzeug和Jinja2两个外部库。Werkzeug是一个WSGI工具包,用于接收和处理HTTP请求,匹配视图函数,支持Cookie和会话管理,交互式调试等功能。Jinja2是一个模板引擎,用于将响应结果渲染到模板文件,支持动态网页的呈现。Flask框架的核心构成简单,但具有很强的扩展性和兼容性,可以根据需要选择不同的数据库和其他功能扩展。Flask框架主要用于开发Web应用程序,例如网站或Web服务。

63aaf4bb43b44194b60af895a9731a0e.png

2.2 ORM技术概述

对象-关系映射(Object-Relational Mapping,简称ORM),面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。ORM框架的架构总览图如2.2所示。

a172d8eed87d42a8beec4379cf99fa29.png

2.3本章小结

本章了解了Flask框架和ORM映射的功能,知道Flask和ORM的关系,下面就对我们制作管理系统的逻辑思维更加明确,更容易做出管理系统。

第3章 需求分析

3.1 系统初步调查

系统初步调查的目标是从系统分析人员和管理人员的角度看新项目开发有无必要和可能,其基本内容包括:系统的基本情况、系统信息处理情况和系统资源情况。

系统初步调查了解到,音乐网站作为一种新兴的一种产业,以其便捷、时尚特点吸引越来越多的人们,抢占市场,并呈现出蓬勃发展的趋势。作为网络时代的产物,音乐网站具有很多新的特点,这些特点充满竞争力,以致成为传统商业的有力挑战者,引发商业革命。

网上音乐市场发展趋势,中国音乐市场的总规模由2017年的210亿元增加至2021年的约666亿元,2017年至2021年的复合年增长率为33.5%。大幅增长主要由同期中国数字音乐及音乐IP市场的快速扩张所推动。根据弗若斯特沙利文,预计2022年,中国音乐市场的总规模预计将达至762亿元。

由上可见,网上音乐网站以投资少、适应性广,成本低,与传统商店相比,网上音乐网站处于初级阶段,尚未形成真正意义的市场,相对于传统市场,有很大发展空间。

3.2 总体需求

系统开发的特点就是实用。系统建设要求达到效率高,使用本系统来实现音乐网系统的使用。主要体现在以下几方面:

具备用户管理功能,包括但不限于用户注册、登录、退出

具备分类功能,根据不同地区、曲风、歌手类型对歌曲分类

具备在线听音乐功能,用户点击选中音乐即可播放

具备排行榜功能,根据用户点击歌曲播放次数进行排名

具备搜索功能,用户根据歌曲名称或歌手名搜索歌曲

具备收藏功能,用户登录之后便可收藏歌曲,可在“我的音乐”中查看

3.3 开发平台

操作系统:window 7及以上

虚拟环境: virtualenv

数据库: PyMySQL驱动+MySQL

开发工具:PyCharm等

开发框架: Flask+ SQLAlchemy + Flask-Script+ Flask-Migrate+ jQuery+ blueprint等

3.4 本章小结

根据市场分析和自己总体确定的需求,计算机对音乐网站进行管理,不仅为音乐网站的管理注入了新的生机,而且在运营过程中节省了大量的人力、物力、财力和时间,可以提高音乐网站的效率,随着计算机技术的发展,以及计算机在各个企事业单位中应用的普及,计算机强大的功能已为人们深刻认识。它在当今高速发展的信息时代占据着不可缺少的地位,作为计算机应用软件的一部分,使用计算机对音乐网站进行综合管理已经远远超过人工管理的效率。


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
数据采集 自然语言处理 数据可视化
优秀python系统案例】基于python Flask的电影票房数据爬取与可视化系统的设计与实现
本文介绍了一个基于Python Flask框架开发的电影票房数据爬取与可视化系统,该系统利用网络爬虫技术从豆瓣电影网站抓取数据,通过Python进行数据处理和分析,并采用ECharts等库实现数据的可视化展示,为电影行业从业者提供决策支持。
优秀python系统案例】基于python Flask的电影票房数据爬取与可视化系统的设计与实现
|
1月前
|
数据采集 数据可视化 关系型数据库
【优秀python web设计】基于Python flask的猫眼电影可视化系统,可视化用echart,前端Layui,数据库用MySQL,包括爬虫
本文介绍了一个基于Python Flask框架、MySQL数据库和Layui前端框架的猫眼电影数据采集分析与可视化系统,该系统通过爬虫技术采集电影数据,利用数据分析库进行处理,并使用Echart进行数据的可视化展示,以提供全面、准确的电影市场分析结果。
|
1月前
|
机器学习/深度学习 数据采集 数据可视化
【优秀python系统毕设】基于Python flask的气象数据可视化系统设计与实现,有LSTM算法预测气温
本文介绍了一个基于Python Flask框架开发的气象数据可视化系统,该系统集成了数据获取、处理、存储、LSTM算法气温预测以及多种数据可视化功能,旨在提高气象数据的利用价值并推动气象领域的发展。
|
1月前
|
存储 数据采集 数据可视化
基于Python flask+MySQL+echart的电影数据分析可视化系统
该博客文章介绍了一个基于Python Flask框架、MySQL数据库和ECharts库构建的电影数据分析可视化系统,系统功能包括猫眼电影数据的爬取、存储、展示以及电影评价词云图的生成。
|
1月前
|
数据采集 存储 数据可视化
基于Python flask的猫眼电影票房数据分析可视化系统,可以定制可视化
本文介绍了一个基于Python Flask框架开发的猫眼电影票房数据分析可视化系统,该系统集成了数据爬取、存储处理、可视化展示和用户交互功能,使用户能够直观地分析和展示电影票房数据,具有高度定制性。
基于Python flask的猫眼电影票房数据分析可视化系统,可以定制可视化
|
1月前
|
数据采集 数据可视化 算法
基于Python flask的boss直聘数据分析与可视化系统案例,能预测boss直聘某个岗位某个城市的薪资
本文介绍了一个基于Python Flask框架的Boss直聘数据分析与可视化系统,系统使用selenium爬虫、MySQL和csv进行数据存储,通过Pandas和Numpy进行数据处理分析,并采用模糊匹配算法进行薪资预测。
基于Python flask的boss直聘数据分析与可视化系统案例,能预测boss直聘某个岗位某个城市的薪资
|
1月前
|
机器学习/深度学习 数据采集 存储
基于Python+flask+echarts的气象数据采集与分析系统,可实现lstm算法进行预测
本文介绍了一个基于Python、Flask和Echarts的气象数据采集与分析系统,该系统集成了LSTM算法进行数据预测,并提供了实时数据监测、历史数据查询、数据可视化以及用户权限管理等功能。
|
1月前
|
机器学习/深度学习 算法 数据可视化
基于Python flask的豆瓣电影数据分析可视化系统,功能多,LSTM算法+注意力机制实现情感分析,准确率高达85%
本文介绍了一个基于Python Flask框架的豆瓣电影数据分析可视化系统,该系统集成了LSTM算法和注意力机制进行情感分析,准确率高达85%,提供了多样化的数据分析和情感识别功能,旨在帮助用户深入理解电影市场和观众喜好。
|
1月前
|
监控 数据可视化 算法
基于朴素贝叶斯算法的微博舆情监控系统,flask后端,可视化丰富
本文介绍了一个基于朴素贝叶斯算法和Python技术栈的微博舆情监控系统,该系统使用Flask作为后端框架,通过数据爬取、清洗、情感分析和可视化等手段,为用户提供丰富的舆情分析和监测功能。
|
1月前
|
机器学习/深度学习 数据可视化 算法
基于python flask的租房数据可视化系统,通过随机森林预测,可以选择条件
本文介绍了一个基于Python Flask框架开发的租房数据可视化系统,该系统集成了随机森林预测算法,允许用户输入租房相关特征并预测价格,同时提供数据可视化功能,帮助用户和房东做出更明智的市场决策。