尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

【从零构建开源音乐社区】音浪星球:用 Django + Vue3 打造的音乐平台

【从零构建开源音乐社区】音浪星球:用 Django + Vue3 打造的音乐平台
📅 发布时间:2026/7/19 6:43:15

去年冬天,一个做独立音乐人的朋友找到我,说想有个地方展示自己的作品。我翻了三天 GitHub,愣是没找到一个既好用又能二次开发的开源音乐项目。既然没有合适的,那就自己写一个吧。这就是 Py-Music 的起点。


📌 一、项目定位与技术选型

1.1 它能做什么?

Py-Music 不是“又一个仿 QQ 音乐”,而是一个功能完整的音乐社区底座。它面向三类人群:

  • 🎸独立音乐人:用这个平台做作品集,展示歌曲、专辑、个人简介
  • 📚全栈学习者:通过这个项目理解 Django + Vue 3 的实战整合
  • 🎓毕设选手:拿来即用,也能按需扩展

核心功能覆盖了音乐平台的常见需求:歌曲上传与播放、歌手专辑管理、歌单收藏、社区动态、评论互动、关注关系……基本上一个音乐社区该有的,它都具备了。

1.2 技术选型:为什么是 Django + Vue 3?🤔

后端:Django 5.x + DRF

选择 Django,核心原因是它的Admin 后台。对于需要频繁管理歌曲、歌手、轮播图的内容型项目,Django Admin + django-simpleui 可以秒出一个漂亮的管理界面,省去大量后台开发时间。配合 DRF 的 ViewSet + ModelSerializer,CRUD 接口几乎是一行代码的事。

前端:Vue 3 + TypeScript + Pinia + Tailwind CSS🎨

Vue 的模板语法接近原生 HTML,对新手友好,Composition API 在大型项目中也不输阵。Pinia 比 Vuex 轻量很多,配合 TypeScript 的类型推导,状态管理的代码量直接砍半。Tailwind CSS 的原子化类让样式开发几乎不用离开 HTML 模板,开发效率非常直观。

认证方案:JWT(djangorestframework-simplejwt)🔐

前后端分离架构下,JWT 是无状态认证的天然选择。配合 refresh token 机制,在安全和体验之间取得了平衡。


🏗️ 二、后端模块设计

2.1 模块划分

按业务领域拆分为 6 个独立应用,实现高内聚低耦合:

模块职责
users注册登录、个人信息、关注关系
music歌曲 CRUD、点赞、热门/新歌推荐
artist歌手管理、专辑管理、歌曲数量自动统计
playlist歌单 CRUD、歌曲添加/移除、公开/私有
community动态发布、评论回复、点赞收藏
system轮播图、导航菜单、文件上传

每个模块遵循标准结构:models.py→serializers.py→views.py→urls.py,确保代码组织清晰,新人也能快速定位。

2.2 核心数据模型设计

用户模块:关注关系的双向查询👥

classFollow(models.Model):follower=models.ForeignKey(User,on_delete=models.CASCADE,related_name='following_set')following=models.ForeignKey(User,on_delete=models.CASCADE,related_name='followers_set')created_at=models.DateTimeField(auto_now_add=True)

通过related_name明确区分「我关注的人」和「关注我的人」,避免 ORM 查询时的语义混淆。

音乐模块:冗余字段提升性能⚡

classSong(models.Model):title=models.CharField(max_length=255)src=models.FileField(upload_to='audio/%Y/%m')cover=models.ImageField(upload_to='image/%Y/%m',null=True,blank=True)play_count=models.IntegerField(default=0)# 冗余字段like_count=models.IntegerField(default=0)# 冗余字段singer=models.ForeignKey('artist.Singer',on_delete=models.SET_NULL,null=True)lyric=models.TextField(blank=True,default='')# LRC 格式歌词

播放量、点赞数冗余存储,避免每次列表查询都做关联聚合,接口响应时间从~200ms 降到 ~50ms🚀。

歌单模块:多对多关系📋

classPlaylist(models.Model):user=models.ForeignKey(User,on_delete=models.CASCADE,related_name='playlists')songs=models.ManyToManyField('music.Song',related_name='playlists',blank=True)is_public=models.BooleanField(default=True)

歌单与歌曲是多对多关系,前端传入歌曲 ID 列表即可批量关联,序列化器负责处理新增和删除的 diff。

📸效果预览:歌单管理界面(创建 / 编辑 / 收藏)

2.3 信号机制:自动维护冗余数据 🔔

在artist/signals.py中,利用 Django 信号自动更新专辑的歌曲数量:

@receiver(post_save,sender=Song)@receiver(post_delete,sender=Song)defupdate_album_song_count(sender,instance,**kwargs):ifinstance.album:instance.album.song_count=instance.album.songs.count()instance.album.save(update_fields=['song_count'])

相比定时任务或手动维护,信号机制实时性好、代码耦合度低。创建、删除、更新歌曲时自动触发,无需在多个视图里重复维护逻辑。

2.4 序列化器的分层设计 📦

列表接口和详情接口使用不同的序列化器:

  • 列表接口:只返回 ID 和关键字段,避免 N+1 查询
  • 详情接口:通过SerializerMethodField嵌套返回歌手、专辑的完整信息
classSongDetailSerializer(serializers.ModelSerializer):singer=serializers.SerializerMethodField()album=serializers.SerializerMethodField()defget_singer(self,obj):returnSingerSimpleSerializer(obj.singer).dataifobj.singerelseNone

创建和更新也拆分为独立的序列化器,避免在同一个类里堆砌复杂的required条件逻辑,代码可读性更好。

2.5 统一响应格式与全局异常处理 🛡️

所有 API 接口返回统一结构:

{"code":200,"message":"操作成功","data":{...}}

全局异常处理器统一捕获 ValidationError、PermissionDenied、IntegrityError 等,返回格式化的错误响应,前端只需一套逻辑即可处理所有接口。


🎨 三、前端架构与状态管理

3.1 目录结构 📁

src/ ├── api/ # 按业务拆分的接口层(song.ts, user.ts, playlist.ts...) ├── components/ # 可复用组件(Player, Navbar, SongList...) ├── stores/ # Pinia 状态管理(auth, player, playlist, navigation...) ├── views/ # 页面视图(Home, Discover, Singer, Play...) ├── router/ # 路由配置 + 路由守卫 ├── types/ # TypeScript 类型定义 └── utils/ # 工具函数(时间格式化、歌词解析...)

3.2 Pinia Store 拆分 🗂️

Store职责
auth用户登录状态、Token 管理、用户信息
player播放列表、当前歌曲、播放状态、进度、音量
playlist歌单列表、当前歌单详情
navigation动态菜单数据(从 API 加载)
ui全局 Loading、弹窗状态

播放器 Store 的核心逻辑:🎵

exportconstusePlayerStore=defineStore('player',()=>{constcurrentSong=ref<Song|null>(null)constplaylist=ref<Song[]>([])constisPlaying=ref(false)constprogress=ref(0)constvolume=ref(0.8)constplay=(song:Song)=>{/* ... */}consttoggle=()=>{isPlaying.value=!isPlaying.value}constnext=()=>{/* 从 playlist 取下一首 */}constprev=()=>{/* 从 playlist 取上一首 */}return{currentSong,playlist,isPlaying,progress,volume,play,toggle,next,prev}})

3.3 全局播放器组件 🎧

播放器悬浮在页面底部,所有视图共享同一个播放实例。关键实现细节:

  • 歌词同步:后端返回 LRC 格式歌词,前端解析为[{time, text}]数组,通过requestAnimationFrame驱动高亮更新。setInterval精度不足,换用rAF后歌词与音频的同步误差控制在±50ms以内。
  • 无缝切换:提前加载下一首音频,在当前歌曲播放到80%时开始缓冲,切换时几乎无感知 ✨。
  • 状态持久化:播放列表和进度写入localStorage,刷新页面后恢复。

📸效果预览:底部全局播放器(含歌词展示)

3.4 动态路由与菜单 🧭

导航菜单从后端 API 动态加载,通过路由守卫在页面加载前注入路由:

// router/guard.tsrouter.beforeEach(async(to,from,next)=>{constnavStore=useNavigationStore()if(!navStore.isLoaded){awaitnavStore.fetchNavigations()navStore.injectRoutes()// 动态添加路由}next()})

API 失败时降级到本地静态菜单数据,确保页面始终可访问。


🔥 四、核心功能实现要点

4.1 热门推荐与轮播图 🖼️

首页展示轮播图、热门歌曲、新歌首发、热门歌单四个模块。所有数据从后端 API 获取,前端通过onMounted并发请求,Promise.allSettled处理部分接口失败的情况,保证页面整体可用。

📸效果预览:首页轮播 + 热门推荐

4.2 社区动态(时间线)📝

采用「拉模式」实现动态时间线:

  • 用户登录后,后端返回其关注的人的最新动态
  • 按时间倒序排列,支持分页
  • 前端配合IntersectionObserver实现无限滚动
// 无限滚动核心逻辑constobserver=newIntersectionObserver((entries)=>{if(entries[0].isIntersecting&&!loading.value&&hasMore.value){loadMore()}})

帖子支持图片、文字、视频多种类型,评论支持嵌套回复,点赞和收藏独立计数 💬。

📸效果预览:社区动态(瀑布流 + 评论框)

4.3 歌手与专辑筛选 🎤

歌手列表支持按字母、地区、性别、风格四维筛选,前端通过 URL query 参数传递筛选条件,后端使用 DRF 的FilterSet处理组合查询。

专辑详情页自动统计歌曲数量,通过信号机制实时更新,无需额外查询。

📸效果预览:歌手详情页(热门歌曲 + 专辑列表)


💣 五、踩坑与优化

5.1 JWT 刷新令牌生命周期 ⏰

问题:未配置 refresh token 的有效期,用户第二天打开页面需要重新登录。

解决:在settings.py中配置REFRESH_TOKEN_LIFETIME = timedelta(days=7),前端在 access token 过期时自动调用/api/refresh接口续期,用户无感知。

5.2 CORS 预检请求拦截 🚧

问题:django-cors-headers配置了白名单,但OPTIONS预检请求仍被拦截。

解决:补充配置:

CORS_ALLOW_METHODS=['DELETE','GET','OPTIONS','PATCH','POST','PUT']

5.3 播放器状态管理混乱 🧩

问题:一开始把播放状态、用户信息、歌单全部塞在一个 store 里,代码臃肿且难以调试。

解决:拆分为auth、player、playlist、navigation、ui五个独立 store,职责边界清晰,维护成本大幅降低。

5.4 歌词同步精度问题 🎤

问题:setInterval在浏览器标签页切到后台时会被节流,导致歌词高亮滞后。

解决:换用requestAnimationFrame,以音频的currentTime为基准驱动歌词渲染,不再依赖定时器精度。


🚀 六、项目运行与部署

6.1 后端启动 🐍

# 克隆项目gitclone<repository-url>cdpy-music# 创建虚拟环境python-mvenv venvsourcevenv/bin/activate# Windows: venv\Scripts\activate# 安装依赖pipinstall-rrequirements.txt# 数据库迁移python manage.py makemigrations python manage.py migrate# 创建超级管理员python manage.py createsuperuser# 启动服务python manage.py runserver0.0.0.0:8000

访问地址:

  • 管理后台:http://localhost:8000/admin/
  • API 接口:http://localhost:8000/api/

6.2 前端启动 ⚡

cdweb-musicnpminstallnpmrun dev

开发服务器默认运行在http://localhost:5173,支持热更新。

6.3 环境变量配置 ⚙️

后端关键配置项位于py_music/settings.py:

# JWT 有效期SIMPLE_JWT={'ACCESS_TOKEN_LIFETIME':timedelta(hours=2),'REFRESH_TOKEN_LIFETIME':timedelta(days=7),}# CORS(生产环境应配置具体域名)CORS_ALLOW_ALL_ORIGINS=True# 媒体文件存储MEDIA_URL='/media/'MEDIA_ROOT=os.path.join(BASE_DIR,'media')

🌟 七、未来可扩展方向

项目当前已具备完整功能,后续可以继续探索的方向:

  • 🧠个性化推荐:基于协同过滤算法,根据用户收听历史推荐相似歌曲
  • 💬实时互动:用 WebSocket 实现直播间或「一起听」功能
  • 💰付费内容:支持独立音乐人发布付费单曲或专辑
  • 📊排行榜:按播放量、点赞数、收藏数生成周榜/月榜

🙌 八、写在最后

这个项目从需求到落地,前后花了几个月时间。它不是那种“一键生成”的脚手架,而是一个从业务出发、经过多次重构的完整系统。如果你正在学习全栈开发,或者需要一个音乐类项目的起点,它应该能帮到你。

项目地址👉 https://gitee.com/walii/py-music

欢迎查阅源码、提出改进建议。如果这个项目对你有帮助,不妨给它点个 Star ⭐,让更多人能看到它。


音乐无界,代码有爱。希望 Py-Music 能成为你技术探索路上的一个小小驿站。✨

相关新闻

  • KPRCB 结构分析与调度流程
  • BAT大厂Android面试核心考点与备战策略
  • 3步解决机械键盘连击问题的终极免费工具指南

最新新闻

  • 3分钟掌握Harvester网络管理:VIP、VLAN与多网卡实战指南
  • 【2026-07】鳞片石墨优秀企业怎么选?石墨增碳剂、石墨粉优选——光耀石墨 - 多才菠萝
  • SplinterDB深度解析:揭秘高性能嵌入式键值存储的核心原理
  • 如何快速批量下载抖音无水印视频:douyin-downloader 完全指南
  • 基于原型的可解释AI:让模型用真实案例说话
  • BilibiliDown:3分钟学会免费下载B站视频的终极指南,轻松收藏任何内容

日新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

周新闻

  • SaaS软件行业GEO实践:AI搜索时代的品牌可见性与获客新路径
  • 什么是PCTFE?医药高端包装的“防潮王牌“材料
  • 【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号