Django实现音乐网站 ⒂

使用Python Django框架制作一个音乐网站,

本篇主要是歌手详情页-基本信息、单曲列表功能开发实现内容。

目录

歌手基本信息

增加路由

显示视图

模板显示

推荐歌手跳转详情

歌手增加基本信息

表模型增加字段

数据表更新

基本信息增加内容渲染

歌手单曲列表

路由设置

跳转设置

视图方法

模板内容

模板公共头信息

单曲列表页面内容

计算歌曲时长

表模型增加方法

模板中使用表模型方法

总结


歌手基本信息

增加路由

需要设置参数歌手id。

path('singer/detail/<int:id>', views.singer_detail, name='singer_detail'),

显示视图

查询歌手表模型,通过id查询响应歌手信息。

def singer_detail(request, id):
    """ 歌手详情-基本信息 """

    info = Singler.objects.get(pk=id)

    return render(request, 'singer/detail.html', {'info': info})

模板显示

设置样式和在模板基础上改为视图中传递的歌手信息。

{% extends 'common/base.html' %}
{% load static %}

{% block title %}我的音乐-歌手{% endblock title %}

{% block content %}
<link rel="stylesheet" href="{% static 'css/singer_detail.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="{% url 'player:singer' %}">单曲</a></li>
        <li><a href="javascript:void(0)">歌单</a></li>
    </ul>
</div>
<!--导航条结束-->

<!--歌手预告开始-->
<div class="singer">
    <div class="singer_bg"></div>
    <div class="singer_info flex_c">
        <div class="singer_cover">
            <img src="/media/{{info.portrait}}" alt="">
        </div>
        <div class="info">
            <p class="flex_c"><span class="name">{{info.name}}</span></p>
            <div class="info_items">
                <span>单曲:<span class="num">{{info.singe_num}}</span></span>
                <span>专辑:<span class="num">{{info.album_num}}</span></span>
                <span>粉丝:<span class="num">100W</span></span>
            </div>
            <div class="singer_items flex_c">
                <p>
                    <span>生日:<span>{{info.birthday}}</span></span>
                    <span>身高:<span>{{info.height}}cm</span></span>
                    <span>体重:<span>{{info.weight}}kg</span></span>
                    <span>星座:<span>{{info.constellation}}...</span></span>
                </p>
                <span class="all"><a href="{% url 'player:singer_detail' info.id %}">全部</a> > </span>
            </div>
            <div class="btns">
                <button class="play"><i class="glyphicon glyphicon-play"></i>&nbsp;&nbsp;播放全部歌曲</button>
                <button><i class="glyphicon glyphicon-heart"></i>&nbsp;&nbsp;收藏</button>
            </div>
        </div>
    </div>
</div>
<!--歌手预告结束-->

<!--歌手资料开始-->
<div class="main_con">
    <div class="con_l">
        <ul class="tabs flex_c">
            <li>
                <span class=""><a href="{% url 'player:singer_song' 1 %}">单曲</a></span>
                <span class=""><a href="{% url 'player:singer_album' 1 %}">专辑</a></span>
                <span class="active">简介</span>
            </li>
        </ul>
        <div class="child_view">
            <p class="tit">基本信息</p>
            <div class="list_info">
                <div class="info_list flex_c">
                    <div class="item_l">
                        <span>姓名:<span class="text">{{info.name}}</span></span>
                    </div>
                    &nbsp;
                    <div class="item_r">
                        <span>英文名:<span class="text">-</span></span>
                    </div>
                </div>
                <div class="info_list flex_c">
                    <div class="item_l">
                        <span>性别:<span class="text">男</span></span>
                    </div>
                    &nbsp;
                    <div class="item_r">
                        <span>国籍:<span class="text">中国香港</span></span>
                    </div>
                </div>
                <div class="info_list flex_c">
                    <div class="item_l">
                        <span>生日:<span class="text">{{info.birthday}}</span></span>
                    </div>
                    &nbsp;
                    <div class="item_r">
                        <span>星座:<span class="text">{{info.constellation}}</span></span>
                    </div>
                </div>
                <div class="info_list flex_c">
                    <div class="item_l">
                        <span>身高:<span class="text">{{info.height}}cm</span></span>
                    </div>
                    &nbsp;
                    <div class="item_r">
                        <span>体重:<span class="text">{{info.weight}}kg</span></span>
                    </div>
                </div>
            </div>
            <p class="tit">个人简介</p>
            <p class="info">{{info.desc|safe}}</p>
        </div>
    </div>
</div>
<!--歌手资料结束-->
{% endblock content %}

 

推荐歌手跳转详情

在推荐页中推荐歌手增加跳转到歌手详情-基本信息页面的链接设置。

<div class="item">
    <div class="cover">
        <img src="/media/{{sg.portrait}}" alt="">
    </div>
    <p class="name"><a href="{% url 'player:singer_detail' sg.id %}">
{{sg.name}}</a></p>
    <p class="num">{{sg.singe_num}}首歌曲</p>
</div>

 

歌手增加基本信息

表模型增加字段

player/models.py中歌手表模型增加英文名、国籍、性别字段。

内容如下:

english_name = models.CharField(
    '英文名',
    max_length=50,
    help_text='请输入歌手英文名',
    default='-'
)
gender = models.IntegerField(
    '性别',
    help_text='请选择歌手性别',
    choices=((0, '女'), (1, '男')),
    default=1
)
country_name = models.CharField(
    '国籍',
    max_length=50,
    help_text='请输入歌手国籍',
    default='-'
)

数据表更新

 同样还要创建表迁移文件,然后执行更新表结构。

python manage.py makemigrations
python manage.py migrate

效果如下:

 

基本信息增加内容渲染

表字段增加以后,对原来的歌手信息进行补录,最后对新增的信息进行模板渲染。

内容如下:

<div class="child_view">
    <p class="tit">基本信息</p>
    <div class="list_info">
        <div class="info_list flex_c">
            <div class="item_l">
                <span>姓名:<span class="text">{{info.name}}</span></span>
            </div>
            &nbsp;
            <div class="item_r">
                <span>英文名:<span class="text">{{info.english_name}}</span></span>
            </div>
        </div>
        <div class="info_list flex_c">
            <div class="item_l">
                <span>性别:<span class="text">
                    {% if info.gender %}
                        男
                    {% else %}
                        女
                    {% endif %}
                </span></span>
            </div>
            &nbsp;
            <div class="item_r">
                <span>国籍:<span class="text">{{info.country_name}}</span></span>
            </div>
        </div>

歌手单曲列表

路由设置

需要设置参数歌手id、分页page。

path('singer/song/<int:id>/<int:page>', views.singer_song, name='singer_song'),

跳转设置

在歌手详情中单曲切换设置跳转链接。

<span class=""><a href="{% url 'player:singer_song' info.id 1 %}">单曲</a></span>

视图方法

还是先获取全部列表,然后传给分页组件得到分页条数。

def singer_song(request, id, page):
    """ 歌手详情-单曲列表 """

    # 歌手基本信息
    info = Singler.objects.get(pk=id)

    # 单曲列表
    song_list = Singe.objects.filter(singler_id=id).all()

    # 实例化Paginator
    paginator = Paginator(song_list, 20)
    # 获取当前页码数据
    res = paginator.page(page)

    return render(request, 'singer/song_list.html', {'info': info, 'songList': res})

模板内容

模板公共头信息

抽离出与歌手基本信息中相同的头部信息,

在singler文件夹中创建common.html文件,

做一个歌手公共头部内容页面。

内容如下:

{% load static %}
<!--导航条开始-->
<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)" class="selected">歌手</a></li>
        <li><a href="javascript:void(0)">单曲</a></li>
        <li><a href="javascript:void(0)">歌单</a></li>
    </ul>
</div>
<!--导航条结束-->

<!--歌手预告开始-->
<div class="singer">
    <div class="singer_bg"></div>
    <div class="singer_info flex_c">
        <div class="singer_cover">
            <img src="/media/{{info.portrait}}" alt="">
        </div>
        <div class="info">
            <p class="flex_c"><span class="name">{{info.name}}</span></p>
            <div class="info_items">
                <span>单曲:<span class="num">{{info.singe_num}}</span></span>
                <span>专辑:<span class="num">{{info.album_num}}</span></span>
                <span>粉丝:<span class="num">100W</span></span>
            </div>
            <div class="singer_items flex_c">
                <p>
                    <span>生日:<span>{{info.birthday}}</span></span>
                    <span>身高:<span>{{info.height}}cm</span></span>
                    <span>体重:<span>{{info.weight}}kg</span></span>
                    <span>星座:<span>{{info.constellation}}...</span></span>
                </p>
                <span class="all"><a href="{% url 'player:singer_detail' info.id %}">全部</a> > </span>
            </div>
            <div class="btns">
                <button class="play"><i class="glyphicon glyphicon-play"></i>&nbsp;&nbsp;播放全部歌曲</button>
                <button><i class="glyphicon glyphicon-heart"></i>&nbsp;&nbsp;收藏</button>
            </div>
        </div>
    </div>
</div>
<!--歌手预告结束-->

单曲列表页面内容

单曲列表页面把原来的模板内容公共部分去掉,通过include引入进来。

接着就是for循环把单曲列表渲染出来;然后做一个分页列表,最后判断无数据显示

固定页面。

注意:需要把歌手基本信息页面也改为引入公共信息处理。

内容如下:

{% extends 'common/base.html' %}
{% load static %}

{% block title %}我的音乐-歌手{% endblock title %}

{% block content %}
<link rel="stylesheet" href="{% static 'css/singer_song.css' %}">

<!--歌手头部公共信息-->
{% include 'singer/common.html' %}

<!--歌手资料开始-->
<div class="main_con">
    <div class="con_l">
        <ul class="tabs flex_c">
            <li>
                <span class="active">单曲</span>
                <span class=""><a href="javascript:void(0)">专辑</a></span>
                <span class=""><a href="{% url 'player:singer_detail' 1 %}">简介</a></span>
            </li>
        </ul>
        <div class="child_view">
            <div class="list_head head_name_singer">
                <ul class="flex_c">
                    <li class="head_num">序号</li>
                    <li class="head_name">歌曲</li>
                    <li class="head_album">歌手</li>
                    <li class="head_time">时长</li>
                </ul>
            </div>
            <ul class="singer_list">
                {% for song in songList %}
                {% if forloop.counter == 1%}
                    <li class="song_item current flex_c">
                {% else %}
                    <li class="song_item flex_c">
                {% endif %}
                        <div class="song_rank flex_c">
                            <div class="rank_num">
                                <span>{{forloop.counter}}</span>
                            </div>
                            <img alt="" class="cover"
                                 data-src="{% static 'images/re_3.jpg' %}"
                                 src="{% static 'images/re_3.jpg' %}" lazy="loaded">
                        </div>
                        <div class="song_name flex_c">
                            <a title="{{song.name}}" href="/play_detail/288010178" class="name">{{song.name}}</a>
                        </div>
                        <div class="song_album">
                            <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>

            {% 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 songList.paginator.page_range %}
                        {% if songList.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 %}

计算歌曲时长

表模型增加方法

单曲列表需要显示歌曲时长,但是数据库存储的是秒数,需要转化为分:秒格式。

而查询出来的查询集是一个对象格式的直接添加属性,下一步还是取不到。

解决方法:需要在表模型类中新增一个方法,去处理转换时长格式。

具体如下:

def get_song_duration(self):
    """ 计算歌曲时长 格式 00:00 """

    secs = self.duration % 60
    if secs:
        mins = (self.duration - secs) / 60
    else:
        mins = self.duration - secs / 60
    return str(int(mins)) + ':' + str(secs)

 

模板中使用表模型方法

直接通过循环出的对象调用模型方法,需要注意不带小括号。

内容如下:

{% for song in songList %}
      {{song.get_song_duration}}
{% endfor %}

总结

基本信息这块没什么难度,使用主键直接查询返回给模板渲染即可;

单曲列表分页还是使用Paginator来做,就时长有点小纠结,

没用过别的python框架,还是感觉数据操作这块很麻烦。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

详解排序算法(附带Java/Python/Js源码)

冒泡算法 依次比较两个相邻的子元素&#xff0c;如果他们的顺序错误就把他们交换过来&#xff0c;重复地进行此过程直到没有相邻元素需要交换&#xff0c;即完成整个冒泡&#xff0c;时间复杂度。 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换它们两个&#xff1b;…

RSA算法与错误敏感攻击

参见《RSA 算法的错误敏感攻击研究与实践》 RSA 算法简介 RSA 算法原理&#xff1a; 1&#xff09; RSA 算法密钥产生过程 &#xff08;1&#xff09;系统随机产生两个大素数 p p p 和 q q q&#xff0c;对这两个数据保密&#xff1b; &#xff08;2&#xff09;计算 n p …

springboot集成es 插入和查询的简单使用

第一步&#xff1a;引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-elasticsearch</artifactId><version>2.2.5.RELEASE</version></dependency>第二步&#xff1a;…

uniapp微信小程序使用stomp.js实现STOMP传输协议的实时聊天

简介&#xff1a; 原生微信小程序中使用 本来使用websocket&#xff0c;后端同事使用了stomp协议&#xff0c;导致前端也需要对应修改。 如何使用 1.yarn add stompjs 2.版本 “stompjs”: “^2.3.3” 3.在static/js中新建stomp.js和websocket.js&#xff0c;然后在需要使用…

Nginx详解 三:高级配置

文章目录 1. 网页的状态页2. Nginx第三方模块2.1 echo模块 3. 变量3.1 内置变量3.1.1 示例 3.2 自定义变量3.2.1 自定义访问日志3.2.2 自定义json 格式日志 3.4 Nginx压缩功能 4. HTTPS4.1 Nginx的HTTPS工作原理4.2 启用功能模块的配置过程 5、自定义图标 1. 网页的状态页 基于…

深度学习在自然语言处理中的十大应用领域

文章目录 1. 机器翻译2. 文本分类3. 命名实体识别4. 问答系统5. 文本生成6. 情感分析7. 语言生成与处理8. 信息检索与摘要9. 文本纠错与修复10. 智能对话系统总结 &#x1f389;欢迎来到AIGC人工智能专栏~深度学习在自然语言处理中的十大应用领域 ☆* o(≧▽≦)o *☆嗨~我是IT陈…

【Kali Linux高级渗透测试】深入剖析Kali Linux:高级渗透测试技术与实践

&#x1f4d5;作者简介&#xff1a;热爱跑步的恒川&#xff0c;致力于C/C、Java、Python等多编程语言&#xff0c;热爱跑步&#xff0c;喜爱音乐的一位博主。 &#x1f4d7;本文收录于恒川的日常汇报系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏C语言初阶、C…

NPM 常用命令(一)

目录 1、npm 1.1 简介 1.2 依赖性 1.3 安装方式 2、npm access 2.1 命令描述 2.2 详情 3、npm adduser 3.1 描述 4、npm audit 4.1 简介 4.2 审计签名 4.3 操作示例 4.4 配置 audit-level dry-run force json package-lock-only omit foreground-scripts …

Ubuntu 下安装Qt5.12.12无法输入中文解决方法

Ubuntu 下安装Qt5.12.12无法输入中文解决方法 一&#xff0c;环境&#xff1a; &#xff08;1&#xff09;VMware Workstation 15 Pro &#xff08;2&#xff09;Ubuntu 20.04 &#xff08;3&#xff09;Qt 5.12.12 64bits &#xff08;4&#xff09;Qt Creator 5.0.2 &#…

浅析Redis(1)

一.Redis的含义 Redis可以用来作数据库&#xff0c;缓存&#xff0c;流引擎&#xff0c;消息队列。redis只有在分布式系统中才能充分的发挥作用&#xff0c;如果是单机程序&#xff0c;直接通过变量来存储数据是更优的选择。那我们知道进程之间是有隔离性的&#xff0c;那么re…

[第七届蓝帽杯全国大学生网络安全技能大赛 蓝帽杯 2023]——Web方向部分题 详细Writeup

Web LovePHP 你真的熟悉PHP吗&#xff1f; 源码如下 <?php class Saferman{public $check True;public function __destruct(){if($this->check True){file($_GET[secret]);}}public function __wakeup(){$this->checkFalse;} } if(isset($_GET[my_secret.flag]…

用AI + Milvus Cloud搭建着装搭配推荐系统教程

以下函数定义了如何将图像转换为向量并插入到 Milvus Cloud 向量数据库中。代码会循环遍历所有图像。(注意:如果需要开启 Milvus Cloud 全新特性动态 Schema,需要修改代码。) 查询向量数据库 以下代码演示了如何使用输入图像查询 Milvus Cloud 向量数据库,以检索和上传…

华为OD机试 - 符合要求的元组的个数 - 回溯(Java 2023 B卷 100分)

目录 一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 一、题目描述 给定一个整数数组nums、一个数字k&#xff0c;一个整数目标值target&#xff0c;请问nums中…

null和undefined区别

1.undefined&#xff0c;表示无值。 比如下面场景&#xff1a; a. 变量被声明了&#xff0c;但是没有被赋值&#xff1b; b. 调用函数的时候&#xff0c;应该给函数传参却没有给函数传这个参数打印出来就是 undefined&#xff1b; c. 访问一个对象中没有的属性&#xff1b;…

【LeetCode-中等题】24. 两两交换链表中的节点

文章目录 题目方法一&#xff1a;递归方法二&#xff1a;三指针迭代 题目 方法一&#xff1a;递归 图解&#xff1a; 详细版 public ListNode swapPairs(ListNode head) {/*递归法:宗旨就是紧紧抓住原来的函数究竟返回的是什么?作用是什么即可其余的细枝末节不要细究,编译器…

实战系列(一)| Dubbo和Spring Cloud的区别,包含代码详解

目录 1. 概述2. 核心功能3. 代码示例4. 适用场景 Dubbo 和 Spring Cloud 都是微服务架构中的重要框架&#xff0c;但它们的定位和关注点不同。Dubbo 是阿里巴巴开源的一个高性能、轻量级的 RPC 框架&#xff0c;主要用于构建微服务之间的服务治理。而 Spring Cloud 是基于 Spri…

数据结构与算法基础-学习-31-交换排序之冒泡排序、快速排序

排序的其他相关知识点和源码分享可以参考之前的博客&#xff1a; 《数据结构与算法基础-学习-30-插入排序之直接插入排序、二分插入排序、希尔排序》 一、交换排序基本思想 两两比较&#xff0c;如果发生逆序则交换位置&#xff0c;直到所有数据记录都排好序为止。 二、冒…

无涯教程-Android - Style Demo Example函数

下面的示例演示如何将样式用于单个元素。让我们开始按照以下步骤创建一个简单的Android应用程序- 步骤说明 1 您将使用Android Studio IDE创建一个Android应用程序,并在 com.example.saira_000.myapplication 包下将其命名为 myapplication ,如中所述您好世界Example一章。 2 …

常用Web漏洞扫描工具汇总(持续更新中)

常用Web漏洞扫描工具汇总 常用Web漏洞扫描工具汇总1、AWVS&#xff0c;2、OWASP Zed&#xff08;ZAP&#xff09;&#xff0c;3、Nikto&#xff0c;4、BurpSuite&#xff0c;5、Nessus&#xff0c;6、nmap7、X-ray还有很多不是非常知名&#xff0c;但可能也很大牌、也较常见的。…

el-date-picker限制选择的时间范围

<el-date-pickersize"mini"v-model"dateTime"value-format"yyyy-MM-dd HH:mm:ss"type"datetimerange"range-separator"~"start-placeholder"开始日期"end-placeholder"结束日期":picker-options&quo…