音乐推荐系统搭建试验

Vue环境搭建:

Node.js,版本为10.13

没找到,官网推荐10.16

https://www.cnblogs.com/zhaomeizi/p/8483597.html

https://nodejs.org/en/下载,安装node,改变安装盘符、默认安装4项

二、设置nodejs prefix(全局)和cache(缓存)路径

1、在nodejs安装路径下,新建node_globalnode_cache两个文件夹

2、设置缓存文件夹

npm config set cache "D:\Program Files\nodejs\node_cache"

 设置全局模块存放路径

npm config set prefix "D:\Program Files\nodejs\node_global"

设置成功后,之后用命令npm install XXX -g安装以后模块就在D:\vueProject\nodejs\node_global里

三、基于 Node.js 安装cnpm(淘宝镜像)

npm install -g cnpm --registry=https://registry.npm.taobao.org

四、设置环境变量

说明:设置环境变量可以使得住任意目录下都可以使用cnpm、vue等命令,而不需要输入全路径

1、鼠标右键"此电脑",选择“属性”菜单,在弹出的“系统”对话框中左侧选择“高级系统设置”,弹出“系统属性”对话框。

2、修改系统变量PATH

五、安装Vue

cnpm install vue -g

六、安装vue命令行工具,即vue-cli 脚手架

cnpm install vue-cli -g

 

七、新项目的创建

1.打开存放新建项目的文件夹,弹出命令提示符

2.根据模版创建新项目

在当前目录下输入“vue init webpack-simple 项目名称(使用英文)”。

vue init webpack-simple mytest

 

3、安装工程依赖模块

定位到mytest的工程目录下,安装该工程依赖的模块,这些模块将被安装在:mytest\node_module目录下,node_module文件夹会被新建,而且根据package.json的配置下载该项目的modules

cd mytest

cnpm install

4、运行该项目,测试一下该项目是否能够正常工作,这种方式是用nodejs来启动。

cnpm run dev

后端搭建

activate MusicRec

cd /d D:\anacondaProject\MusicRec\z-others\files

pip install -r requirement.txt

运行说明

mysql新建musicrec数据库,将MusicRecSys/MusicRec/z-others/files/musicrec.sql 文件导入

修改 MusicRecSys/MusicRec/MusicRec/settings.py 文件中的ALLOWED_HOSTS为本地IP地址和本地mysql配置信息

修改 MusicRecSys/MusicRec-Vue/config/index.js 中的 serverUrl

修改 MusicRecSys/MusicRec-Vue/src/assets/js/linkBase.js 中的 serverUrl

 

进入 MusicRecSys/MusicRec 执行python manage.py runserver 0.0.0.0:8000

activate MusicRec

cd /d D:\anacondaProject\MusicRec

python manage.py runserver 0.0.0.0:8000

进入 MusicRecSys/MusicRec-Vue 执行npm install / npm run dev

cd /d D:\Workspaces\Vue\MusicRec-Vue

输入

npm install

npm run dev

浏览器输入 http://127.0.0.1:8001 访问

 

npm install时有警告

D:\Workspaces\Vue\MusicRec-Vue>npm install

npm WARN [email protected] requires a peer of ajv@^5.0.0 but none is installed. You must install peer dependencies yourself.

npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules\fsevents):

npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

 

audited 29868 packages in 43.88s

found 778 vulnerabilities (67 low, 11 moderate, 699 high, 1 critical)

  run `npm audit fix` to fix them, or `npm audit` for details

成功run

     

admin,admin

实现细节

Django编写接口

参考https://www.cnblogs.com/sixrain/p/9138442.html

Django 是用Python开发的一个免费开源的Web框架,可以用于快速搭建高性能,优雅的网站。Django 中提供了开发网站经常用到的模块,常见的代码都为你写好了,减少重复的代码。

 

Django 目录结构

urls.py

网址入口,关联到对应的views.py中的一个函数(或者generic类),访问网址就对应一个函数。

views.py

处理用户发出的请求,从urls.py中对应过来, 通过渲染templates中的网页可以将显示内容,比如登陆后的用户名,用户请求的数据,输出到网页。

models.py

与数据库操作相关,存入或读取数据时用到这个,当然用不到数据库的时候 你可以不使用。

forms.py

表单,用户在浏览器上输入数据提交,对数据的验证工作以及输入框的生成等工作,当然你也可以不使用。

templates 文件夹

views.py 中的函数渲染templates中的Html模板,得到动态内容的网页,当然可以用缓存来提高速度。

admin.py

后台,可以用很少量的代码就拥有一个强大的后台。

settings.py

Django 的设置,配置文件,比如 DEBUG 的开关,静态文件的位置等。

 

URL:

有关详细信息,请参阅:

    https://docs.djangoproject.com/en/2.1/topics/http/urls/

例子:

函数视图Function views

    1. 添加导入:from my_app import views

    2. 将 URL 添加到  URLPATTERNS:path('', views.home, name='home')

基于类的view,Class-based views

    1. 添加导入:from other_app.views import Home

    2. 将 URL 添加到  URLPATTERNS:path('', Home.as_view(), name='home')

Including another URLconf

    1. 导入 include() 功能:from django.urls import include, path

2. 将 URL 添加到  URLPATTERNS:path('blog/', include('blog.urls'))
Setting.py

在MusicRec文件夹中

接口

接口使用rest_frameworkrest_framework是一套基于Django  REST 框架,是一个强大灵活的构建 Web API 的工具包。

写接口三步完成:连接数据库、取数据、数据输出 

1)连接数据库

在工程目录下的settings.py文件下配置

2)取数据

既然要取数据,那model肯定得和数据库的一致,我发现一个快捷的方式可以把数据库中的表生成对应的model,在项目目录下执行命令

python manage.py inspectdb

取我们表的model拷贝到app下的models.py

class Meizis(models.Model):

    mid = models.CharField(max_length=10)

    title = models.CharField(max_length=50, blank=True, null=True)

    picname = models.CharField(max_length=10, blank=True, null=True)

    page_url = models.CharField(max_length=50, blank=True, null=True)

    img_url = models.CharField(max_length=50, blank=True, null=True)

 

    class Meta:

        managed = False

        db_table = 'meizi_meizis'

创建一个序列化Serializer类

提供序列化和反序列化的途径,使之可以转化为,某种表现形式如json。我们可以借助serializer来实现,类似于Django表单(form)的运作方式。在app目录下,创建文件serializers.py。

这样在views.py就可以来获取数据库的数据了

meizis = Meizis.objects.all()

serializer = MeiziSerializer(meizis, many=True)

return Response(serializer.data)

3) 数据输出客户端或前端

 REST框架提供了两种编写API视图的封装。

@api_view装饰器,基于方法的视图。

继承APIView类,基于类的视图。

 

request.data会自行处理输入的json请求

使用格式后缀明确的指向指定的格式,需要添加一个format关键字参数

http://127.0.0.1:8000/getlist.json # JSON 后缀

http://127.0.0.1:8000/getlist.api # 可视化 API 后缀

http://127.0.0.1:8000/getlist/ code="print 123"post

最后别忘了在urls.py配置URL,通过浏览器就可以看到json数据了。

4)分页

我们的数据有好几千条,一块返回来很不合理,所以需要分页,当然rest_framework框架提供了这个功能,post请求不支持,需要自己查数据库或者切片来进行返回

views.py里编写

@api_view(['GET'])

def getlist(request, format=None):

    if request.method == 'GET':

        meizis = Meizis.objects.values('mid','title').distinct()

        # http: // 127.0.0.1:8000 / getlist?limit = 20

        # http: // 127.0.0.1:8000 / getlist?limit = 20 & offset = 20

        # http: // 127.0.0.1:8000 / getlist?limit = 20 & offset = 40

        # 根据url参数 获取分页数据

        obj = StandardResultSetPagination()

        page_list = obj.paginate_queryset(meizis, request)

        # 对数据序列化 普通序列化 显示的只是数据

        ser = ListSerialize(instance=page_list, many=True)  # 多个many=True # instance:把对象序列化

        response = obj.get_paginated_response(ser.data)

        return response

源码获取推荐

# 获取单个歌单的推荐

def getRecBasedOne(pl_id):

    pl_tags = PlayList.objects.filter(pl_id= pl_id).values("pl_tags")[0]["pl_tags"]

    pl_tags_list = pl_tags.replace(" ","").split(",")

    print(pl_tags_list)

    results = list(PlayList.objects.filter(pl_tags=pl_tags).filter(~Q(pl_id=pl_id)))

    if results.__len__() < 10:

        for tag in pl_tags_list:

            for pl in PlayList.objects.filter(pl_tags__contains=tag):

                results.append(pl)

                if results.__len__() >= 10:

                    break

            if results.__len__() >= 10:

                break

    # print(results)

    # 拼接返回结果

    rec_pl_list = list()

    for one in results:

        rec_pl_list.append({

            "id": one.pl_id,

            "name": one.pl_name,

            "creator": one.pl_creator.u_name,

            "img_url": one.pl_img_url,

            "cate": "2"

        })

    return rec_pl_list

可以看出,歌曲的推荐通过tag选取。

# 获得歌曲、歌单标签推荐

def getSongAndPlRecTags(songs, base_click):

    song_tags = list()

    pl_tags =  list()

    if base_click == 1: # 表示前端是基于点击行为进入为你推荐模块

        click_songs = UserBrowse.objects.filter(click_cate="3").values("click_id")

        if click_songs.__len__() != 0:

            for one in click_songs:

                filter_one = SongTag.objects.filter(song_id=one["click_id"])

                if filter_one.__len__() != 0 and filter_one[0].tag not in song_tags:

                    song_tags.append(filter_one[0].tag)

 

                # 歌单tag

                pl_one = PlayListToSongs.objects.filter( song_id=filter_one[0].song_id )

                if pl_one.__len__() !=0:

                    for pl_tag_one in PlayListToTag.objects.filter(pl_id=pl_one[0].song_id):

                        if pl_tag_one.tag not in pl_tags:

                            pl_tags.append(pl_tag_one.tag)

 

        if songs.__len__() != 0:  # 表示前端选择了相关歌曲

            for sing in songs:

                choose_one = SongTag.objects.filter(song_id=sing)

                if choose_one.__len__() != 0 and choose_one[0].tag not in song_tags:

                    song_tags.append(choose_one[0].tag)

 

                    # 歌单tag

                    pl_one = PlayListToSongs.objects.filter(song_id=choose_one[0].song_id)

                    if pl_one.__len__() != 0:

                        for pl_tag_one in PlayListToTag.objects.filter(pl_id=pl_one[0].song_id):

                            if pl_tag_one.tag not in pl_tags:

                                pl_tags.append(pl_tag_one.tag)

        # print("songs_tags_by_click %s" % songs_tags_by_click)

        # print("pl_tags_by_click %s" % pl_tags_by_click)

    else:     # 表示用户是首次进入为你推荐模块

        if songs.__len__() != 0:  # 表示前端选择了相关歌曲

            for sing in songs:

                choose_one = SongTag.objects.filter(song_id=sing)

                if choose_one.__len__() != 0 and choose_one[0].tag not in song_tags:

                    song_tags.append(choose_one[0].tag)

 

                    # 歌单tag

                    pl_one = PlayListToSongs.objects.filter(song_id=choose_one[0].song_id)

                    if pl_one.__len__() != 0:

                        for pl_tag_one in PlayListToTag.objects.filter(pl_id=pl_one[0].song_id):

                            if pl_tag_one.tag not in pl_tags:

                                pl_tags.append(pl_tag_one.tag)

            # print("songs_tags_by_choose: %s" % songs_tags_by_choose)

            # print("pl_tags_by_choose: %s" % pl_tags_by_choose)

    # 如果 click 和 choose的tag不够 以 hot来补充

    if song_tags.__len__() < 15:

        hot_tag_dict = dict()

        for one in SongTag.objects.all():

            hot_tag_dict.setdefault(one.tag, 0)

            hot_tag_dict[one.tag] += 1

        tag_dict_song = sorted(hot_tag_dict.items(), key=lambda k: k[1], reverse=True)[:15-song_tags.__len__()]

        for one in tag_dict_song:

            if one[0] not in song_tags:

                song_tags.append(one[0])

        # print("songs_tags_by_hot: %s" % songs_tags_by_hot)

 

    # 如果 click 和 choose的tag不够 以 hot来补充

    if pl_tags.__len__() < 15:

        hot_tag_dict = dict()

        for one in PlayListToTag.objects.all():

            hot_tag_dict.setdefault(one.tag, 0)

            hot_tag_dict[one.tag] += 1

        tag_dict_pl = sorted(hot_tag_dict.items(), key=lambda k: k[1], reverse=True)[:15-pl_tags.__len__()]

        for one in tag_dict_pl:

            if one[0] not in pl_tags:

                pl_tags.append(one[0])

        # print("pl_tags_by_hot: %s" % pl_tags_by_hot)

 

    return song_tags,pl_tags

而这些标签来源于:用户选择的标签,用户行为对象对应的标签,热门标签

猜你喜欢

转载自blog.csdn.net/lagoon_lala/article/details/100670710