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>&nbsp;下载该专辑</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>&nbsp;<span>立即播放</span></button><button><i class="glyphicon glyphicon-plus"></i>&nbsp;<span>添加</span></button><button><i class="glyphicon glyphicon-heart"></i>&nbsp;<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())

总结

本篇主要实现歌手详情中的专辑列表和专辑详情中单曲列表,

综合使用了分页、外键查询、连表查询、模板中的循环、判断标签及对分页进行优化。

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

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

相关文章

v-model和v-bind

v-model&#xff0c;它其实就是一个语法糖&#xff0c;作用就是双向绑定表单控件&#xff08;radio, text,address,email,select,checkbox,textarea&#xff09; v-bind(简写形式:value值),用于绑定属性值&#xff0c;只能实现数据的单项绑定。 <template> <div>…

9.2 消息对话框 画板 定时器

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//设置定时器timernew QTimer(this);timeidthis->startTimer(1000);connect(timer,&QTimer::timeout,this,&Widget::timeout_slot);speechernew QTextToSpeech(this);//边框this-&…

字节码和机器码的区别

字节码和机器码是计算机程序在不同阶段的表示形式&#xff0c;它们的主要区别如下&#xff1a; 抽象级别不同&#xff1a;字节码是一种中间表示形式&#xff0c;位于源代码和机器码之间。它是一种与特定平台无关的低级表示形式&#xff0c;通常由编译器将源代码转换而来。而机器…

AP51656 LED车灯电源驱动IC 兼容替代PT4115 PT4205 PWM和线性调光

产品描述 AP51656是一款连续电感电流导通模式的降压恒流源 用于驱动一颗或多颗串联LED 输入电压范围从 5V 到 60V&#xff0c;输出电流 可达 1.5A 。根据不同的输入电压和 外部器件&#xff0c; 可以驱动高达数十瓦的 LED。 内置功率开关&#xff0c;采用高端电流采样设置 …

Qt中布局管理使用总结

目录 1. 五大布局 1.1 QVBoxLayout垂直布局 1.2 QHBoxLayout水平布局 1.3 QGridLayout网格布局 1.4 QFormLayout表单布局 1.5 QStackedLayout分组布局 1.6 五大布局综合应用 2. 分割窗口 3. 滚动区域 4. 停靠区域 1. 五大布局 1.1 QVBoxLayout垂直布局 #include <…

华为mate60的发布代表着什么?有什么意义?

华为Mate60的发布代表着华为在技术领域的持续突破和创新。该产品预计将引入更强大的处理器、更高分辨率的屏幕、更强大的摄像头等前沿技术&#xff0c;进一步巩固华为在技术领域的领先地位。 此外&#xff0c;华为Mate60的发布还具有重塑品牌形象的意义。在美国制裁下&#xff…

服装商城小程序制作:打造便捷购物体验和提升销售额的利器

随着移动互联网的发展&#xff0c;服装商城小程序成为各大服装品牌推广销售的重要工具。它不仅能够为用户提供便捷的购物体验&#xff0c;还能帮助服装商城实现更高效的销售和管理。下面给大家介绍下服装商城小程序的优点以及制作流程&#xff0c;让您了解并充分利用这一利器。…

Vue + Element UI 前端篇(一):搭建开发环境

Vue Element UI 实现权限管理系统 前端篇&#xff08;一&#xff09;&#xff1a;搭建开发环境 技术基础 开发之前&#xff0c;请先熟悉下面的4个文档 vue.js2.0中文, 优秀的JS框架vue-router, vue.js 配套路由vuex&#xff0c;vue.js 应用状态管理库Element&#xff0c;饿…

海域可视化监管:浅析海域动态远程视频智能监管平台的构建方案

一、方案背景 随着科技的不断进步&#xff0c;智慧海域管理平台已经成为海洋领域监管的一种重要工具。相比传统的视频监控方式&#xff0c;智慧海域管理平台通过建设近岸海域视频监控网、海洋环境监测网和海上目标探测网络等&#xff0c;可实现海洋管理的数字化转型。 传统的…

Springboot + Sqlite实战(离线部署成功)

最近有个需求&#xff0c;是手机软件离线使用&#xff0c; 用的springboot mybatis-plus mysql&#xff0c;无法实现&#xff0c;于是考虑使用内嵌式轻量级的数据库SQLlite 引入依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-…

车载域控制器DCU浪涌防护推荐TVS二极管

为了解决分布式EEA的这些问题&#xff0c;汽车工程师开始逐渐把很多功能相似、分离的ECU功能集成整合到一个比ECU性能更强的处理器硬件平台上&#xff0c;这就是汽车“域控制器&#xff08;Domain Controller Unit&#xff0c;DCU&#xff09;”。车载域控制器DCU大大优化整车的…

星辰天合 CEO 胥昕受邀参加人民网 2023 “小巨人”发展论坛

为进一步推动专精特新“小巨人”企业高质量发展&#xff0c;近日&#xff0c;由人民网主办&#xff0c;人民网财经研究院、828 企业服务平台共同承办的 2023“小巨人”发展论坛在人民日报社新媒体大厦举行&#xff0c;星辰天合 CEO 胥昕受邀参加。 2023 “小巨人”发展论坛现场…

如何将DHTMLX Suite集成到Scheduler Lightbox中?让项目管理更可控!

在构建JavaScript调度器时&#xff0c;通常需要为最终用户提供一个他们喜欢的方式来计划事件&#xff0c;这是Web开发人员喜欢认可DHTMLX Scheduler的重要原因&#xff0c;它在这方面提供了完全的操作自由&#xff0c;它带有lightbox弹出窗口&#xff0c;允许通过各种控件动态更…

linux信号量

通过学习linux的信号量&#xff0c;对linux的信号量进行了编程。

Fragment.onStop的事情

继续承接上一篇文章----Fragment.OnPause的事情&#xff0c;我们知道onPause之后进入的是onStop生命周期方法&#xff0c;那Fragment的onStop方法又干了些什么呢&#xff1f; 还是从Activity入手&#xff0c;相应的入口代码如下&#xff1a; //FragmentActivity.java/*** Disp…

7英寸触摸显示屏企业网络电话

SV-X77英寸触摸显示屏企业网络电话 SV-X7网络电话是一款带有7英寸触摸显示屏的高端式企业级电话&#xff0c;以先进设计及强大的功能大幅度提高企业工作效率。 功能亮点 √ 虚拟可编程按键 — 可动态显示4个分页&#xff0c;每页可设置显示29个DSS键的状态&#xff0c;最多支持…

设计模式之适配器与装饰器

目录 适配器模式 简介 角色 使用 优缺点 使用场景 装饰器模式 简介 优缺点 模式结构 使用 使用场景 适配器模式 简介 允许将不兼容的对象包装成一个适配器类&#xff0c;使得其他类可以通过适配器类与原始对象进行交互&#xff0c;从而提高兼容性 角色 目标角色…

Debezium-增量迁移之 Oracle 迁移所需权限

-- 创建用户 create user TCK identified by oracle; -- 赋权 grant connect,resource to TCK; -- 删除权限 revoke select any table from TCK&#xff1b; revoke select any DICTIONARY from TCK&#xff1b; -- 删除用户 CASCADE(用户下的数据级联删除) drop user TCK CASC…

拼多多订单打单接口 免申请审核流程接入(拼多多开放平台接入)

pdd.erp.order.sync erp打单信息同步 更新时间&#xff1a;2021-04-13 23:04:54 免费API必须用户授权 erp打单信息同步 公共参数 名称类型必须描述keyString是调用key&#xff08;注册获取APIkey&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff…

JS中的扩展操作符...(点点点)

标题 前言概述拓展操作符&#xff08;Spread Operator&#xff09;赋值与扩展操作符的区别 剩余操作符&#xff08;Rest Operator&#xff09; 前言 大家应该都在代码中用过或者看到…方法&#xff0c;我每次用到这个方法的时候都会想到第一次见到这个方法一头雾水的样子&#…