Django实现音乐网站 ⒃
使用Python Django框架制作一个音乐网站,
本篇主要是歌手详情页-专辑列表、专辑详情-单曲列表开发实现内容。
目录
歌手详情-专辑列表
路由设置
跳转设置
视图方法
模板内容
专辑详情-单曲列表
设置路由
视图处理并返回
模板渲染
分页优化
引入错误类型库
分页实例
总结
歌手详情-专辑列表
通过歌手名称进入歌手详情,再点击专辑可查看歌手拥有专辑列表。
路由设置
需要设置参数歌手id、分页page。
path('singer/album/<int:id>/<int:page>', views.singer_album, name='singer_album'),
跳转设置
在歌手详情中专辑切换设置跳转链接。
<span class=""><a href="{% url 'player:singer_album' info.id 1 %}">专辑</a></span>
视图方法
查询歌手信息,通过歌手外键id查询歌手所拥有的专辑列表,之后进行分页。
def singer_album(request, id, page):""" 歌手详情-专辑列表 """# 歌手基本信息info = Singler.objects.get(pk=id)# 专辑列表album_list = Album.objects.filter(singler_id=id).all()# 实例化Paginatorpaginator = Paginator(album_list, 20)# 获取当前页码数据res = paginator.page(page)return render(request, 'singer/album_list.html', {'info': info,'albumList': res,'list_num': len(album_list)})
模板内容
通过两个for循环渲染专辑列表和分页列表,if判断后显示无数据内容。
{% extends 'common/base.html' %}
{% load static %}{% block title %}我的音乐-歌手{% endblock title %}{% block content %}
<link rel="stylesheet" href="{% static 'css/singer_album.css' %}"><!--歌手头部公共信息-->
{% include 'singer/common.html' %}<!--歌手资料开始-->
<div class="main_con"><div class="con_l"><ul class="tabs flex_c"><li><span class=""><a href="{% url 'player:singer_song' info.id 1 %}">单曲</a></span><span class="active">专辑</span><span class=""><a href="{% url 'player:singer_detail' 1 %}">简介</a></span></li></ul><div class="child_view"><div class="albums">{% for album in albumList %}<div class="album_item"><div class="cover_out"><div class="cover_play"><span class="play icon_play"><i class="glyphicon glyphicon-play"></i></span></div><div class="img_out"><img alt="" class="cover pic" src="/media/{{album.cover}}" lazy="loaded"></div><img src="{% static 'images/album_record.png' %}" alt="" class="record"></div><p class="name"><span title="{{album.name}}"> <a href="{% url 'player:album' album.id %}">{{album.name}}</a></span></p><p class="time">{{album.addtime}}</p></div>{% endfor %}</div>{% if list_num < 1 %}<!--设置无数据内容--><div class="nodata flex_c"><div class="inner"><img src="{% static 'images/nodata.png' %}"alt="" class="nodata_img"><div class="tip"><p>暂无相关数据</p></div></div></div>{% endif %}{% if list_num > 1 %}<div class="page"><i class="li-page glyphicon glyphicon-menu-left notPointer"></i><ul>{% for index in albumList.paginator.page_range %}{% if albumList.number == index %}<li><a href="#" class="notCursor currentPage">{{index}}</a></li>{% else %}<li><a href="{% url 'player:singer' index %}">{{index}}</a></li>{% endif %}{% endfor %}</ul><i class="glyphicon glyphicon-menu-right li-page"></i></div>{% endif %}</div></div>
</div>
<!--歌手资料结束-->
{% endblock content %}
专辑详情-单曲列表
通过歌手详情-专辑列表跳转到专辑详情-单曲列表。
设置路由
专辑详情没有分页,只需要设置专辑id参数即可。
path('album/<int:id>', views.album, name='album'),
视图处理并返回
这里就有些复杂,虽然代码比较少,还是有些技术含量的。
专辑表和单曲表是多对多的关系,查询时需要prefetch_related进行关联对应表模型。
def album(request, id):""" 专辑详情-单曲列表 """# 查询专辑信息# 通过 prefetch_related 关联对应表模型 进行多对多的关联查询info = Album.objects.prefetch_related('Singe').filter(id=id).first()# 专辑单曲列表song_list = info.Singe.all()return render(request, 'album/index.html', {'info': info,'songList': song_list})
模板渲染
模板渲染与歌手-单曲列表模板处理差不多,只需要注意歌手名称的显示和单曲时长显示。
内容如下:
{% extends 'common/base.html' %}
{% load static %}{% block title %}我的音乐-歌手{% endblock title %}{% block content %}
<link rel="stylesheet" href="{% static 'css/album.css' %}"><!--导航条开始-->
<div class="header"><img src="{% static 'images/logo.png' %}" class="logo" alt=""><ul><li><a href="{% url 'player:index' %}">推荐</a></li><li><a href="javascript:void(0)">排行榜</a></li><li><a href="javascript:void(0)" class="selected">歌手</a></li><li><a href="javascript:void(0)">单曲</a></li><li><a href="javascript:void(0)">歌单</a></li></ul>
</div>
<!--导航条结束--><!--专辑内容开始-->
<div class="main_con"><div class="content"><div class="info_l"><div class="cover_out"><img src="/media/{{info.cover}}" alt="" class="cover" data-src="info.cover" lazy="loaded"><img src="{% static 'images/album_cover_record.png' %}" alt="" class="record"></div><p class="intr">专辑简介 </p><p class="intr_txt">{{info.desc}}...</p><div><a href="javascript:;" class="download bg_primary"><i class="glyphicon glyphicon-download-alt"></i> 下载该专辑</a></div></div><!--专辑单曲列表开始--><div class="info_r"><div loading-text="正在加载中..."><p class="song_name">{{info.name}}</p><p class="artist_name"><span>{{info.single.name}}</span></p><p class="song_info"><span>语种:</span><span class="tip">{{info.single_lang}}</span><span>发行时间:{{info.addtime}}</span></p><div class="btns"><button class="play bg_primary"><i class="glyphicon glyphicon-play"></i> <span>立即播放</span></button><button><i class="glyphicon glyphicon-plus"></i> <span>添加</span></button><button><i class="glyphicon glyphicon-heart"></i> <span>收藏</span></button></div><div><div class="list_head head_name_album"><ul class="flex_c"><li class="head_num">序号</li><li class="head_name">歌曲</li><li class="head_artist">歌手</li><li class="head_time">时长</li></ul></div><ul class="album_list">{% for song in songList %}<li class="song_item flex_c"><div class="song_rank flex_c"><div class="rank_num"><span>{{forloop.counter}}</span></div></div><div class="song_name flex_c"><a title="{{song.name}}" href="/play_detail/226555042" class="name">{{song.name}}</a></div><div class="song_artist"><span title="{{song.singler.name}}">{{song.singler.name}}</span></div><div class="song_time"><span>{{song.get_song_duration}}</span></div><div class="song_opts flex_c"><i class="glyphicon glyphicon-plus"></i><i class="glyphicon glyphicon-play"></i><i class="glyphicon glyphicon-heart"></i></div></li>{% endfor %}</ul></div>{% if info == False %}<!--设置无数据内容--><div class="nodata flex_c"><div class="inner"><img src="{% static 'images/nodata.png' %}"alt="" class="nodata_img"><div class="tip"><p>暂无相关数据</p></div></div></div>{% endif %}</div></div><!--专辑单曲列表结束--></div>
</div>
<!--专辑内容结束-->
{% endblock content %}
分页优化
分页原来的处理比较简单,只是实现分页功能,没有处理分页范围。
这次在原来的基础上,对超出总页数和页数为空情况进行处理。
引入错误类型库
from django.core.paginator import EmptyPage, PageNotAnInteger
分页实例
在try...except判断中处理分页判断并进行处理;
通过使用locals函数对传递模板的参数进行优化,不需要再单独赋值。
内容如下:
def singer_album(request, id, page):""" 歌手详情-专辑列表 """# 歌手基本信息info = Singler.objects.get(pk=id)# 专辑列表albumList = Album.objects.filter(singler_id=id).order_by('-id').all()# 实例化Paginatorpaginator = Paginator(albumList, 20)try:res = paginator.page(page)except PageNotAnInteger:res = paginator.page(1)except EmptyPage:res = paginator.page(paginator.num_pages)return render(request, 'singer/album_list.html', locals())
总结
本篇主要实现歌手详情中的专辑列表和专辑详情中单曲列表,
综合使用了分页、外键查询、连表查询、模板中的循环、判断标签及对分页进行优化。
相关文章:
Django实现音乐网站 ⒃
使用Python Django框架制作一个音乐网站, 本篇主要是歌手详情页-专辑列表、专辑详情-单曲列表开发实现内容。 目录 歌手详情-专辑列表 路由设置 跳转设置 视图方法 模板内容 专辑详情-单曲列表 设置路由 视图处理并返回 模板渲染 分页优化 引入错误类型库…...
【开发问题系列】CSV转Excel
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...
mysql物理备份步骤
原库10.153.88.5,新建数据库实例10.153.88.6,注意/etc/my.cnf配置和88.5一致,测试目的是通过copy数据文件到88.6来恢复数据库。 在数据库10.153.88.5打包数据文件: [mysqlt3-dtpoc-dtpoc-web04 mysql]$ cd /testdata/mysql [mys…...
react使用hook封装一个tab组件
目录 react使用hook封装一个tab组件Tabbar.jsx使用组件效果 react使用hook封装一个tab组件 Tabbar.jsx import PropsTypes from "prop-types"; import React, { useEffect, useState } from react; export default function Tabbar(props) {const { tabData , cur…...
java详细安装教程(供参考)一一java(jdk)安装
一、java历史简介 1991 年Sun公司的James Gosling等人开始开发名称为 Oak (橡树)的语言。希望用于控制嵌入在有线电视交换盒、PDA等的微处理器, 1994年将Oak语言更名为Java 1998年JDK1.2时,更名为Java 2 Platform 分为标准版J…...
C++函数内联详解
本文旨在讲解C中的函数内联相关知识,读完这篇文章,希望读者们会对函数内联有更深一步的认识! 内联函数的定义 在计算机科学中, 内联函数 (有时称作 在线函数 或 编译时期展开函数 )是一种编程语言结构&…...
Revit SDK 介绍:NewForm 新建体量
前言 这个例子介绍如何新建体量。 内容 图形生成效果。 用 Extrusion 创建体量 // 创建一个轮廓 ReferenceArray ref_ar new ReferenceArray(); // 创建三条直线,并放入轮廓 Autodesk.Revit.DB.XYZ ptA new Autodesk.Revit.DB.XYZ(10, 10, 0); Autodesk.Rev…...
Ubuntu离线或在线安装Python解释器
这里以安装Python3.5.7为例。 首先进入官网,下载Python-3.5.7.tgz,或者使用以下命令下载(需要联网): wget https://www.python.org/ftp/python/3.5.7/Python-3.5.7.tgz下载完成后,使用以下命令进行解压缩…...
微信小程序隐私协议相关接口实际使用方式
<view wx:if"{{showPrivacy}}" class"privacy"><view class"popup"><view>隐私弹窗内容....</view><view bindtap"openPrivacyAgreement">点击查看隐私协议</view><button id"disagreeBt…...
MySQL--MySQL表的增删改查(进阶)
check 聚合查找 count sum average max min 我们这里先构造出多张表 查询lisi同学的成绩 来自student和来自score c 增加名字这一条件 查询所有同学的总成绩以及个人信息 来自score和来自student 查询所有同学的各科成绩以及个人信息 来自student,course和…...
Golang 中的静态类型和动态类型
定义说明 静态类型(static type):在编码时就能确定的类型,通过变量定义可以确定的类型;动态类型(concrete type):在运行时才能确定具体的数据类型; 动态静态类型如何理…...
docker的数据卷、docker数据持久化
目录 前言docker数据持久化的2种方式数据卷 bind mount ,即-v参数匿名数据卷 docker manager volume-v参数和匿名卷的区别docker volume 命令的使用数据卷容器孤儿volume总结 前言 环境:centos7.9 docker version 20.10.14 本篇我们来介绍docker的数据卷…...
阅读源码工具Sourcetrail
收费工具Source Insight、Understand Sourcetrail开源工具 一、下载安装 接下来就是download,在GitHub的release页面选择自己系统对应的发布版本下载安装: 安装好后,运行程序,会出现这样的界面: 二、应用 选择“New…...
KMP 算法详解
KMP算法详解 1 KMP算法解决的问题 2 前缀问题 3 KMP 算法 1 KMP算法解决的问题 字符串str1和str2,str1是否包含str2,如果包含返回str2在str1中开始的位置。并做到时间复杂度为 O ( n ) O(n) O(n) 2 前缀问题 求一个字符串中每个字符前缀和后缀相…...
[matconvnet]matconvnet-1.0-beta-25在cuda11.1以上编译问题总结
首先可以肯定是matconvnet-1.0-beta-25不支持cuda11.1及其以上版本,因为cudnn版本问题导致源码api接口不一样,会下面类似报错 E:\Matlab\R2020a\matconvnet-1.0-beta25\matlab\src\bits\datacu.hpp(89): error: identifier "cudnnConvolutionFwdPr…...
自动化驱动程序管理
在部署操作系统时,每次都从下载和分发所需的驱动程序中实现真正的独立性可能是一场艰苦的战斗。特别是具有硬件多样化的环境,并且需要支持新的硬件类型时。借助 OS Deployer,可以对所有端点使用一个映像,无论品牌和型号如何&#…...
智能合约编写高级篇(二)区块哈希介绍
本文档从区块哈希基本概念出发,详细介绍了中移链的区块哈希交易接口和应用方向。适用于EOS区块链智能合约高级开发人员,熟悉如何获取当前发生交易所在的区块号和区块哈希前缀,并通过Tapos机制验证交易的有效性。 01 概述 (一&…...
二进制链表转整数
给你一个单链表的引用结点 head。链表中每个结点的值不是 0 就是 1。已知此链表是一个整数数字的二进制表示形式。 请你返回该链表所表示数字的 十进制值 。 示例 1: 输入:head [1,0,1] 输出:5 解释:二进制数 (101) 转化为十进…...
Python爬虫进阶:使用Scrapy库进行数据提取和处理
在我们的初级教程中,我们介绍了如何使用Scrapy创建和运行一个简单的爬虫。在这篇文章中,我们将深入了解Scrapy的强大功能,学习如何使用Scrapy提取和处理数据。 一、数据提取:Selectors和Item 在Scrapy中,提取数据主要…...
五)Stable Diffussion使用教程:文生图之高清修复
上一篇我们说到图生图,这一篇来说说高清修复。 上一篇我们通过一个例子实现了图生图的功能,使用一张图片生成了另一种风格的图片。 然而,我们生成的图片质量不尽如人意。 虽然我们之前也提到设置分辨率、精炼提示词去提升画面质量等等,但是实际用下来发现,分辨率拉得太…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
