一、任务简介
后端任务:
1.音乐信息的获取,包括歌曲名称、歌曲演唱者、歌曲时长、歌曲封面图片链接以及歌曲的URL链接
2.将音乐信息保存至数据库
3.实现数据库音乐资源的获取返回给前端
前端任务:
实现用户的登录注册页面,正确与后端进行数据交互
二、项目环境及使用工具
Python 3.7
Django 1.11.13
Mysql 8.0.16
python爬虫
Django与爬虫使用Pycharm开发完成
Vue 2.9.6
Node 14.2.0
Vue项目使用VScode开发完成
同时使用Github版本控制工具
三、后端实现
1.Django基本环境搭建
(1)pycharm新建一个Django项目:自动在项目目录下创建虚拟环境,并自动安装所需要的依赖包,包括pip、django等。同时会建立一个与项目名称相同的目录,里面包含项目的配置文件。
(2)修改数据库配置,改为mysql数据库。settings.py配置文件中,把默认的sqllite数据库换成mysql数据库
(3)新建一个项目app:控制台输入 python manage.py startapp [appname] 并将新建的app加入到app列表里
(4)数据库信息迁移:python manage.py migrate
2.Django后台接口实现
(1)数据的建表在新建app的models.py里。在其中建立项目数据库所需的表。
(2)定义接口在项目总配置的urls.py和项目app的自建urls.py里,可以实现多级路由。
(3)后台接口的实现在app目录下的views.py里。在其中数据库交互实现具体的业务逻辑。包含播放下载搜索。下面是部分实现函数:
3.音乐信息的爬虫实现
(1)爬取的音乐来源丰富,包含请求音乐、网易云音乐、酷狗音乐
在爬虫这部分一开始遇到了很多的瓶颈,经过不断尝试最终实现了这个功能需求。
(2)爬取的数据自动添加到数据库
数据的设置:
导入pymsql依赖包
配置mysql数据库
(3)数据库信息的更新
由于从其他网站上爬取的歌曲链接不稳定,所以需要定时更新数据库。
(4)django与爬虫实现统一
开始是django与爬虫是分开的,音乐信息的爬取与更新需要手动完成,与初衷不符。在仔细研究django框架之后发现django每次启动是都会先加载一边新建app下的views.py
文件,所以尝试了这个方法,最终实现了音乐信息的自动获取与更新
四、前端实现
(1)使用vue-cli脚手架搭建项目
(2)登录注册界面编写
<script> import { setCookie, getCookie } from ‘../assets/js/cookie.js‘ export default { data () { return { showLogin: true, showRegister: false, showTishi: false, tishi: ‘‘, username: ‘‘, password: ‘‘, newUsername: ‘‘, newPassword: ‘‘, newPassword_again: ‘‘, tel: ‘‘ } }, mounted () { /* 页面挂载获取cookie,如果存在username的cookie,则跳转到主页,不需登录 */ if (getCookie(‘username‘)) { this.$router.push(‘/home‘) } }, methods: { login () { if (this.username === ‘‘ || this.password === ‘‘) { alert(‘请输入用户名或密码‘) } else { let data = new FormData() data.append(‘username‘, this.username) data.append(‘password‘, this.password) /* 接口请求 */ this.$axios.post(‘/login‘, data).then(res => { // console.log(‘asdasdas‘) console.log(res.data) // alert(res.data.ret) /* 接口的传值是(-1,该用户不存在),(0,密码错误),同时还会检测管理员账号的值 */ if (res.data.ret === -1) { this.tishi = res.data.msg this.showTishi = true } else if (res.data.ret === 0) { this.tishi = ‘登录成功‘ this.showTishi = true setCookie(‘username‘, this.username, 10) setTimeout(function () { this.$router.push(‘/home‘) }.bind(this), 1000) } }) } }, ToRegister () { this.showLogin = false this.showRegister = true }, register () { if (this.newUsername === ‘‘ || this.newPassword === ‘‘ || this.newPassword_again === ‘‘ || this.tel === ‘‘) { alert(‘请正确输入信息‘) } else { let data = new FormData() data.append(‘username‘, this.newUsername) data.append(‘password‘, this.newPassword) data.append(‘confirm_password‘, this.newPassword_again) data.append(‘tel‘, this.tel) this.$axios.post(‘/register‘, data).then(res => { console.log(res.data) if (res.data.ret === -1) { this.tishi = res.data.msg this.showTishi = true } else if (res.data.ret === 0) { this.tishi = ‘注册成功‘ this.showTishi = true } }) } }, ToLogin () { this.showRegister = false this.showLogin = true this.showTishi = false } } } </script>
<template> <body id="poster"> <div class="login-wrap" v-show="showLogin"> <h3 class="login_title">账号登录</h3> <p v-show="showTishi">{{ tishi }}</p> <input type="text" placeholder="请输入用户名" v-model="username" /> <input type="password" placeholder="请输入密码" v-model="password" /> <button v-on:click="login">登录</button> <span v-on:click="ToRegister">没有账号?马上注册</span> </div> <div class="register-wrap" v-show="showRegister"> <h3 class="register_title">注册账号</h3> <p v-show="showTishi">{{ tishi }}</p> <input type="text" placeholder="请输入用户名" v-model="newUsername" /> <input type="password" placeholder="请输入密码" v-model="newPassword" /> <input type="password" placeholder="请再次输入密码" v-model="newPassword_again" /> <input type="text" placeholder="请输入电话号码" v-model="tel" /> <button v-on:click="register">注册</button> <span v-on:click="ToLogin">已有账号?马上登录</span> </div> </body> </template>
<style> #poster { background: url("../assets/eva.jpg") no-repeat; background-position: center; height: 100%; width: 100%; background-size: cover; position: fixed; } body { margin: 0px; } .login-wrap { border-radius: 15px; background-clip: padding-box; margin: 90px auto; width: 350px; padding: 35px 35px 15px 35px; background: #fff; border: 1px solid #eaeaea; box-shadow: 0 0 25px #cac6c6; } .register-wrap { border-radius: 15px; background-clip: padding-box; margin: 90px auto; width: 350px; padding: 35px 35px 15px 35px; background: #fff; border: 1px solid #eaeaea; box-shadow: 0 0 25px #cac6c6; } .login_title { margin: 0px auto 40px auto; text-align: center; color: #505458; } .register_title { margin: 0px auto 40px auto; text-align: center; color: #505458; } input { display: block; width: 250px; height: 40px; line-height: 40px; margin: 0 auto; margin-bottom: 10px; outline: none; border: 1px solid #888; padding: 10px; box-sizing: border-box; } p { color: red; } button { display: block; width: 250px; height: 40px; line-height: 40px; margin: 0 auto; border: none; background-color: gray; color: #fff; font-size: 16px; margin-bottom: 5px; } span { cursor: pointer; } span:hover { color: #41b883; } </style>
(3)效果
五、GIT工具的使用
基本操作
基础操作
-
状态查看操作
git status
- 查看工作区、暂存区状态
-
添加操作
git add [file name]
- 将工作区的“新建/修改”添加到暂存区
-
提交操作
git commit -m "commit message" [file name]
- 将暂存区的内容提交到本地库
-
分支操作
-
创建分支
git branch [分支名]
-
查看分支
-
git branch -v
-
查看远程分支
git branch -r
-
查看所有分支
git branch -a
-
-
切换分支
git checkout [分支名]
-
将新分支推送到GitHub
git push origin [分支名]
-
删除本地分支
git branch -d [分支名]
-
删除Github远程分支
git push origin :[分支名]
- 分支名前的
:
代表删除
-
合并分支
-
切换到接受修改的分支(被合并,增加新内容)上
git checkout [被合并分支名]
-
执行
merge
命令git merge [有新内容分支名]
-
-
强制提交本地分支覆盖远程分支
git push origin [分支名] --force
-