flask搭建在线音乐网系统

news2024/11/28 4:49:47

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

 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  论文结构与章节安排

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

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

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

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

第2章 相关技术

2.1 Flask框架介绍

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

   

 

2.2 ORM技术概述

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

 

2.3本章小结

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

                 

第3章 需求分析

3.1 系统初步调查

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

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

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

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

3.2 总体需求

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

  1. 具备用户管理功能,包括但不限于用户注册、登录、退出
  2. 具备分类功能,根据不同地区、曲风、歌手类型对歌曲分类
  3. 具备在线听音乐功能,用户点击选中音乐即可播放
  4. 具备排行榜功能,根据用户点击歌曲播放次数进行排名
  5. 具备搜索功能,用户根据歌曲名称或歌手名搜索歌曲
  6. 具备收藏功能,用户登录之后便可收藏歌曲,可在“我的音乐”中查看

3.3 开发平台

操作系统:window 7及以上

虚拟环境: virtualenv

数据库: PyMySQL驱动+MySQL

开发工具:PyCharm等

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

3.4 本章小结

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

第4章 系统概要设计

4.1 系统设计概述

系统设计是在系统分析的基础上由抽象到具体的过程,同时,还要考虑系统所实现的条件,系统设计的主要任务就是从管理信息系统出发,根据系统分析阶段对系统的逻辑功能的要求,并考虑经济、技术的条件,确保系统目标的实现。

4.2 系统用例图

  1. 用户可以根据自己喜欢来查询歌曲。
  2. 用户可以选择自己喜欢的歌曲进行播放。
  3. 用户可以对自己喜欢的歌曲进行收藏。

管理员的操作:

  1. 管理员可以根据用户不喜欢的歌曲进行删除。
  2. 管理员可以添加流行的歌曲。
  3. 管理员可以根据不同条件查询歌曲。

4.3 系统流程图

系统功能结构图:

 

用户的功能结构图:

 

管理员功能结构图:

 

4.4 系统功能分析

根据系统和市场调研,音乐网系统前台分为五大模块,它们分别是推荐功能模块,歌曲显示模块,歌手显示模块,排行榜模块,用户使用模块,创建了一些简单的功能。下面是四大模块的功能:

推荐功能模块:根据最流行的歌曲进行推荐。

歌曲显示模块:分类显示最新的歌曲,按类别分页显示各类歌曲。

歌手显示模块:分类显示最流行的歌手,按照类别来显示各个地区的歌手。

歌曲排行榜模块: 播放次数排行。

用户使用模块:收藏歌曲,搜索歌曲,连续播放歌曲,查看歌手。

本系统后台分为2大模块,它们分别是歌曲管理模块和歌手管理模块,下面是它们的功能:

歌曲管理模块:可以根据歌曲名称和歌手名字和歌曲文件地址和分类进行新增歌曲,还可以在歌曲列表下面进行修改和删除。

歌手管理模块:可以根据歌手姓名和歌手分类和歌手照片进行增加歌手,也可以在歌手列表下进行删除和修改。

前台页面的概述:

访问在线音乐网站时,首先进入的是网站的前台页面,需要进行注册和登录才能进去网站,登录进去首先看到是推荐页面,然后点击各个功能都会弹出相关的功能。

后台页面的概述:

访问在线音乐网站后,需要在前台登录mr管理员账号后,再从上面网页上搜索127.0.0.1:5000/manager_artist_list才能进去后台网站,为了防止用户进去后台,进行非法操作,特意设置了只能管理员账号才能进入。

4.5 本章小结

本章介绍了系统的原理图和整个系统的功能,还对整个系统的功能做了详细的概述,对整个系统的各个模块也做了详细的概述,可以让大家知道整个系统的功能和各个模块的功能。

    

5.1数据库结构设计

本系统采用Mysql作为访问数据库的服务器,用它来对数据进行存储,在数据库应用系统的开发过程中,数据库的结构设计是指数据库中各个表的设计,包括系统中的信息保存在哪个数据库中以及各个表之前的关系,数据库的好坏直接对应用系统实现的效果产生影响,好的数据库结构设计会减少数据库的存储,数据库的完整性比较高,系统具有较快的响应速度,简化基于此数据库的应用程序的实现。

5.1.1数据库表

   综合实际来说,图书管理系统library的数据库主要包含如图所示的5张数据表。

用户和管理账号密码表:

 

 

歌手数据表:

歌曲数据表:

 

    

第6章 系统具体实现

6.1 项目基础框架搭建

Flask项目搭建:

1、已有Python、PyCharm后,创建新项目(自定目录,建议启用VirtualEnv)新环境—解释器

 

  1. 可在命令行pip install安装Flask,也可以在Pycharm的Python解释器下”+”安装,还要按照Flask的一些模块包,如下图所示:

 

6.2 系统功能模块实现

 系统功能模块分为推荐功能模块,歌曲显示模块,歌手显示模块,排行榜模块,用户使用模块,管理歌手歌曲模块界面。

6.2.1 推荐功能模块实现

推荐功能模块是运用前端技术和flask框架的视图和数据库最后渲染出前端网页,管理员和用户账号都能登录也能看到,打开网页进入看到第一个页面就是推荐歌曲功能,把最流行的歌曲和歌手给你推荐出来,页面如下所示:

 

6.2.2 用户登录功能实现

 登录页面主要是用户和管理员先注册账号后,才能进行登录,登录功能中连接数据库了,如果账号密码可以到数据库查看,当账号密码错误则会提示账号密码错误,否则正常进入系统,页面如下图所示:

 

6.2.3用户注册功能实现

 用户注册功能是先通过注册用户名和密码和确认密码,然后才能登录,才能进入网页,这是运用前端网页最后渲染模板实现的,页面如下图所示:

 

6.2.4 歌曲播放功能实现

歌曲播放功能是用户登录后,进入页面后,随便点击一首歌曲他就能播放,也可以随时暂停,还可以随时控制音量,这是运用前端网页和flask框架的一些模板,最后渲染出来最后达到我们需要的效果,页面如下图所示:

 

 6.2.5歌曲查询实现

歌曲查询功能,登录用户或者管理账号后点击发现音乐,上面有个搜索功能,随时可以通过歌曲名称找到自己喜欢的歌曲进行播放,页面如下图所示:

6.2.6 排行榜功能实现:

排行榜功能是点击排行榜进去后,通过播放次数最多的歌曲进行排序,还会推荐一些热门的歌手,页面如下所示:

 

6.2.7曲风功能实现

曲风功能是根据不同歌手的唱歌风格来分成的,这里分为华语、欧美、日语、韩语、其他5种风格类型,页面如下所示:

 

       

6.2.8 歌手功能实现

歌手功能实现也是根据曲风进行分类的,这里分为华语、欧美、日语、韩语、其他5种歌手类型,点击每个类型都会弹出对应的歌手,页面如下图所示:

 

6.3 管理员功能实现

管理员功能主要分为歌曲管理和歌手管理方面,这两个类型可以让管理员更好的参与管理音乐网系统,还能随时上传流行歌曲来吸引人们。

6.3.1 歌手管理功能实现

歌手管理是管理员只有的权限,登录mr管理员的账号后,要在该网页上面加manager_artist_list才能进入该网页,进去后,可以对前台里面的歌手的信息随时修改,也能新增流行的歌手,页面如下所示:

 

6.3.2 歌曲管理功能实现

歌手管理是管理员只有的权限,登录mr管理员的账号后,要在该网页上面加manager_artist_list才能进入该网页,进去后,可以对前台里面的歌曲的信息随时修改,也能新增流行的歌曲进去吸引用户,页面如下所示:

 

 6.4 本章小结

通过最初的需求,对每个功能实现的页面,和每个功能的操作做了详细的讲解,也可以知道这些功能实现所使用到的软件。

第7章 系统测试

7.1系统测试方法介绍

该系统在本地服务器上运行和调试,鉴于对系统的内部结构和处理算法的完全了解以及对系统功能的全面掌握对系统进行了测试。

模块功能测试使用正确数据、错误数据、边界数据进行测试,保证平台的正常运行。

7.2 系统功能测试

1. 注册用户,输入自己的用户名和自己设置密码,两次密码要一致,最后点击注册。

 2.登录用户,输入自己刚刚注册的用户名和密码进行登录,如密码不正确,会报账号密码错误。

 3.登录成功进去的是推荐功能页面,点击歌曲,就会播放,点击收藏歌曲,可到我的音乐中查看。

 4.点击发现音乐,进入的是一个搜索功能,点击搜索能找到自己喜欢的歌曲。

 5.点击排行榜,可以看到流行歌手和播放次数最多的歌曲靠前。

 6.点击曲风,会找到自己喜欢曲子风格的不同歌曲。

 7.点击歌手,会根据风格找到自己喜欢的歌手人物。

 8,登录管理员账号后,进入系统后,可以管理歌手和歌曲,更好的管理音乐网系统。

7.3系统测试结果

通过测试音乐网系统功能测试,已经检测完毕用户登录模块、用户注册模块、每个功能的运行测试,音乐网系统的功能都很正常,音乐网系统为了产品后期推广运营提供了强力的技术支撑。

7.4 音乐网系统实现全过程

1.创建项目Online Music

文件夹结构

 

2. 配置虚拟环境

安装virtualenv:pip install virtualenv -i https://pypi.douban.com/simple(如果已安装virtualenv,这条命令可不执行,可使用 where virtualenv 查看是否已安装)

创建虚拟环境:virtualenv  venv

激活虚拟环境 :venv\Scripts\activate

3. 安装项目所需的库(requirements.txt)

pip install -r requirements.txt -i https://pypi.tsinghua.edu.cn/simple

4. 创建各类型文件,并编写源码

5. 创建music数据库,并根据自己的数据库账号密码配置数据库和数据库名

6. 在Terminal中使用migrate创建数据表

 python manage.py db init  # 创建迁移数据库,首次使用

python manage.py db migrate # 创建迁移脚本

 python manage.py db upgrade # 把迁移应用到数据库中

  1. 新建数据库music表

 

 

  1. 运行 python manage.py runserver

7.5 本章小结

测试过程中按照严格的方式进行测试,没有发现音乐网系统存在的问题,各个功能都已实现,实现这些功能,经历了2周的时间,保证了音乐网系统完成自己需要的需求,音乐网系统可以使用户拥有自己的音乐库,也能让管理更好管理音乐网系统。

第8章.总结

8.1工作总结

经过两周的设计和开发,我对音乐网系统基本开发完毕,其功能能够符合应用需求,对于研发中出现的数据问题也通过百度解决了,通过这次设计能体会到自己技术的提升,还可以巩固上课学过的知识和学习新的语言并掌握,我们实习是做软件开发,刚开始我们在课程上只学过前端和js,我们软件开发只能用到这几个,后面经过几个月的实习,现在对js代码挺熟练应用起来,这个设计是经过自己在学校用心学的知识积累起来做成的一个毕业设计。

刚开发时,我遇到js上的许多问题,后面我专门用了两个月对js的学习,以及和比较厉害的同学一起讨论,最后能够解决,这个设计是完完整整的开发,在上半学期,flask的开发老师在课上只教一些简单的开发,我就从那时候慢慢了解它的原理,知道flask和django原理的开发,开发一个系统起来根本不难,但是加上js的系统开发就比较难啦,这个系统html+css+js+flask还有数据库开发出来的,这个设计可以给自己提供一个锻炼、提高的计划。

完成音乐网系统的各个功能和结构的设计, 本次项目让我更加深刻地体会到了前端框架的强大与便利,加深了我对Flask框架的认识,也更加了解了从客户端到服务器端,从请求到响应的过程,还有各种模型图的建立,把这些结合起来,为以后接手新的项目,处理打下基础。

参考文献

1.徐晓东. Flask 框架在音乐分析系统的应用研究[J]. 现代情报, 2019,39(4): 202-205.

2.韩玉涛, 杨慧君. 基于 Flask 的音乐系统播放设计与实现[J]. 计机技术与发展, 2019, 29(7): 153-156+160.

3.马万里. 基于 Java的在线音乐系统设计与实现[J]. 计算机与数字工程, 2018(23): 53-54.

4.石静, 赵艳洪. 基于 Flask 的音乐系统设计与实现[J]. 现代电子技术, 2019(10): 177-178+181.

5.李亚军, 郑玲玲. 基于 Flask 的音乐系统开发[J]. 电子技术应用, 2016, 42(5): 110-114.

致谢

 经过二个星期的设计和开发,在线音乐网系统基本开发完毕。其功能基本符合需求,能够完成歌曲播放,歌曲歌手推荐。界面提供浏览式,使用户可以得到一个属于自己的音乐网系统。

  这二周的开发,实际结合学习了一年多的前端知识结合起来的,使我提高了操作能力,虽然在设计过程中出现一些困难,但是在自身学习和老师的帮助下都克服了,在本次设计中,首先感谢我的指导老师,改论文是在指导老师张超老师的指导下完成的,老师理论知识都使我受益匪浅,他无论在理论和实际都给我很大帮助,使我技术得到提高,这些帮助在今后的工作和学习上都是一种巨大的帮助, 本次项目让我更加深刻地体会到了前端框架的强大与便利,加深了我对Flask框架的认识,也更加了解了从客户端到服务器端,从请求到响应的过程在设计过程中,明白只有努力才能走向成功,再次感谢我的老师和同学们,时光如逝,岁月如初,转眼大学三年就要结束了,这三年中,在惠州经济职业技术学院留下很多美好的回忆。然而天下没有不散的宴席,我们即将各奔东西,走向社会,走向属于我们的未来,同时感谢惠州经济职业技术学院全体老师对我的教育和培养。

 

 总结:

当我们完成了这个Flask音乐系统的开发,我们深刻地意识到,Flask框架的简洁、高效、灵活的特点,使得它成为了一个非常适合构建小型Web应用程序的工具。通过本次开发,我们不仅加深了对Flask框架的理解和应用,同时也提升了我们对Web应用程序的开发能力。

在这个音乐系统中,我们实现了用户注册、登录、注销、上传歌曲、搜索歌曲、播放歌曲等常见功能。这些功能的实现,离不开Flask框架提供的路由、模板、表单、数据库等功能模块。

在开发过程中,我们还遇到了一些问题,比如如何优化数据库查询效率、如何处理上传文件等。通过查阅Flask官方文档和相关资料,我们成功地解决了这些问题,并对Web应用程序的开发过程有了更深入的认识。

最后,我们要感谢Flask框架的开发者以及社区的支持和贡献,让我们能够轻松地开发出一个功能完备、美观实用的音乐系统。我们也希望通过本次开发,能够为其他想要学习Flask框架的开发者提供一些参考和帮助。

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/646778.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java社区文化宣传网站设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…

2023年5月国产数据库大事记-墨天轮

本文为墨天轮社区整理的2023年5月国产数据库大事件和重要产品发布消息。 目录 5月国产数据库大事记 TOP105月国产数据库大事记&#xff08;时间线&#xff09;产品/版本发布兼容认证代表厂商大事记排行榜新增数据库厂商活动 5月国产数据库大事记 TOP10 5月国产数据库大事记&…

高考之后想学习网络安全,网络安全/信息安全是一个好的专业吗?

本人信息安全专业毕业&#xff0c;在甲方互联网大厂安全部与安全乙方大厂都工作过&#xff0c;有一些经验可以供对安全行业感兴趣的人参考。 或许是因为韩商言让更多人知道了CTF&#xff0c;也或许是因为网络安全越来越受国家重视&#xff0c;安全最近愈加火爆了。当然&#x…

C++初阶—list深度解剖及模拟实现

目录 ➡️0. 前言 &#x1f60a;1.简易框架实现 &#x1f414;1. list和__list_node分析实现 &#x1f414;2. 无参构造 &#x1f60a;2.迭代器实现 &#x1f414;1. list普通迭代器面临问题及解决方案 &#x1f414;2. __list_node\iterator\list三类分析 &#x1f41…

内网安全:Cobalt Strike 与 MSF 联动( 会话 相互转移 )

内网安全&#xff1a;Cobalt Strike 与 MSF 联动&#xff08; 会话 相互转移 &#xff09; 在渗透中&#xff0c;有时候 Cobalt Strike 会话可能会受限制&#xff0c;所以我们需要把 Cobalt Strike 会话转移到 MSF 上进行后面的渗透。也有的时候会话在 MSF 上&#xff0c;但是…

大数据学习归纳

本文初衷是为了学习归纳&#xff0c;若有错误&#xff0c;请指出。 修改记录 时间内容2020年4月10日第一次发布2020年4月16日添加MaxCompute SQL部分2020年9月14日新增数仓部分笔记 大数据架构 基础知识题 大数据组件概念 集群&#xff1a;多个人做同样的事 分布式&#xff1a;…

Visual Studio Community 2022 + Win10 编译 OpenCPN 5.9.0 记录

前言 前两天尝试用vs2017编译OpenCPN5.0.0&#xff0c;前后折腾了两三天总算编译成功了。官网给出的编译过程比较简单&#xff0c;我在实际编译过程中遇上了很多很多的问题&#xff0c;最多的就是缺少库&#xff0c;好在最后编译通过了。 后来浏览OpenCPN官网的时候发现发布了…

【Spring】开发框架Spring核心技术含Resource接口详细讲解

前言 Spring 是 Java EE 编程领域的一款轻量级的开源框架&#xff0c;由被称为“Spring 之父”的 Rod Johnson 于 2002 年提出并创立&#xff0c;它的目标就是要简化 Java 企业级应用程序的开发难度和周期。 Spring 自诞生以来备受青睐&#xff0c;一直被广大开发人员作为 Java…

测试工程师常用的10个python库,面试必备哦

目录 前言 1、os库 2、sys库 3、time库 4、selenium库 5、unittest库 6、pytest库 7、email库 8、appium库 9、pymsql库 10、requests库 总结&#xff1a; 前言 今天给各位小伙伴带来的是测试工程师常用的10个python库&#xff0c;相信有些小伙伴肯定知道一些库&am…

aclocal-1.14 is missing on your system

在编译 bluez 的时候出现如下错误&#xff1a; 没有找到 aclocal-1.14&#xff0c; 但是有 aclocal-1.13 版本的&#xff0c;那最直接的方法就是修改 Makefile了&#xff0c;搜索出来 Makefile 指定了 aclocal-1.14&#xff0c;修改成 aclocal-1.13 即可。修改完还会有如下的错…

数据科学导论

《数据科学导论》 重点归纳 第1~4章 数据科学研究的问题边角广泛&#xff0c;只要是和数据收集、清洗整理、分析和挖掘有关的问题都是数据科学要研究的问题&#xff1b;数据科学的主要方法&#xff1a;有监督学习、无监督学习、半监督学习&#xff1b;有监督学习中&#xff…

初见PlayWright

PlayWright特色 跨浏览器&#xff1a;PlayWright支持所有现代的浏览器渲染引擎&#xff0c;包括Chromium、WebKit、Firefox&#xff0c;这意味着它可以驱动像Chrome、Edge、Firefox、Safari等主流浏览器跨平台&#xff1a;基于浏览器的特性&#xff0c;可以在Windows、Linux和…

卡方检验笔记

文章目录 一、定义二、用途三、公式四、案例4.1 手工统计4.2 python统计4.3 SPSS统计 一、定义 卡方检验属于非参数检验&#xff0c;由于非参检验不存在具体参数和总体正态分布的假设&#xff0c;所以有时被称为自由分布检验。原假设 H 0 H_{0} H0​&#xff1a;观察频数与期望…

大龄、零基础,想转行做网络安全。怎样比较可行?一般人我还是劝你算了吧

昨晚上真的给我气孕了。 对于一直以来对网络安全兴趣很大&#xff0c;想以此作为以后的职业方向的人群。 不用担心&#xff0c;你可以选择兼顾工作和学习&#xff0c;以步步为营的方式尝试转行到网络安全领域。 那么&#xff0c;网络安全到底要学些什么呢&#xff1f; &…

怎么快速给需要的网路标记颜色?

引入 我们在走线的时候&#xff0c;需要知道那些类型的线需要先走&#xff0c;接下来又要走那些类型的线&#xff0c;然后依次走完&#xff0c;如果在团队中&#xff0c;这一类型的线分配给这个人走&#xff0c;哪一类型的线有分配给那个人走。而在不管是那单个人&#xff0c;还…

效果图渲染的几大实用技巧

效果图渲染是建筑、室内、景观、产品设计等行业中非常重要的一环。一个高质量的效果图可以让客户更好地了解和感受设计方案&#xff0c;提高设计师的竞争力。但是渲染效果的好坏和速度都取决于设计师的技巧和工具。本文将介绍几大实用技巧&#xff0c;帮助设计师更好地进行效果…

ASEMI代理光宝IGBT驱动器LTV-155E规格,LTV-155E封装

编辑-Z LTV-155E参数描述&#xff1a; 型号&#xff1a;LTV-155E 储存温度Tstg&#xff1a;-55~125℃ 工作温度Topr&#xff1a;-40~105℃ 输出IC结温度TJ&#xff1a;125℃ 总输出电源电压(VCC –VEE)&#xff1a;35V 平均正向输入电流IF&#xff1a;25mA 反向输入电压…

对vite的理解

&#x1f431; 个人主页&#xff1a;不叫猫先生&#xff0c;公众号&#xff1a;前端舵手 &#x1f64b;‍♂️ 作者简介&#xff1a;2022年度博客之星前端领域TOP 2&#xff0c;前端领域优质作者、阿里云专家博主&#xff0c;专注于前端各领域技术&#xff0c;共同学习共同进步…

强化学习笔记-13 Policy Gradient Methods

强化学习算法主要在于学习最优的决策&#xff0c;到目前为止&#xff0c;我们所讨论的决策选择都是通过价值预估函数来间接选择的。本节讨论的是通过一个参数化决策模型来直接根据状态选择动作&#xff0c;而不是根据价值预估函数来间接选择。 我们可以定义如下Policy Gradien…

软件测试外包干了3年,感觉废了..

先说一下自己的情况&#xff0c;大专生&#xff0c;18年通过校招进入湖南某软件公司&#xff0c;干了接近3年的功能测试&#xff0c;今年年初&#xff0c;感觉自己不能够在这样下去了&#xff0c;长时间呆在一个舒适的环境会让一个人堕落!而我已经在一个企业干了3年的功能测试&…