Django实现音乐网站 ⒂

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

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

目录

歌手基本信息

增加路由

显示视图

模板显示

推荐歌手跳转详情

歌手增加基本信息

表模型增加字段

数据表更新

基本信息增加内容渲染

歌手单曲列表

路由设置

跳转设置

视图方法

模板内容

模板公共头信息

单曲列表页面内容

计算歌曲时长

表模型增加方法

模板中使用表模型方法

总结


歌手基本信息

增加路由

需要设置参数歌手id。

python 复制代码
path('singer/detail/<int:id>', views.singer_detail, name='singer_detail'),

显示视图

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

python 复制代码
def singer_detail(request, id):
    """ 歌手详情-基本信息 """

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

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

模板显示

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

python 复制代码
{% 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 %}

推荐歌手跳转详情

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

html 复制代码
<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中歌手表模型增加英文名、国籍、性别字段。

内容如下:

python 复制代码
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='-'
)

数据表更新

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

bash 复制代码
python manage.py makemigrations
python manage.py migrate

效果如下:

基本信息增加内容渲染

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

内容如下:

python 复制代码
<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。

python 复制代码
path('singer/song/<int:id>/<int:page>', views.singer_song, name='singer_song'),

跳转设置

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

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

视图方法

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

python 复制代码
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文件,

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

内容如下:

python 复制代码
{% 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循环把单曲列表渲染出来;然后做一个分页列表,最后判断无数据显示

固定页面。

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

内容如下:

python 复制代码
{% 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 %}

计算歌曲时长

表模型增加方法

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

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

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

具体如下:

python 复制代码
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)

模板中使用表模型方法

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

内容如下:

python 复制代码
{% for song in songList %}
      {{song.get_song_duration}}
{% endfor %}

总结

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

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

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

相关推荐
黄公子学安全21 分钟前
Java的基础概念(一)
java·开发语言·python
Yuan_o_27 分钟前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端
程序员一诺1 小时前
【Python使用】嘿马python高级进阶全体系教程第10篇:静态Web服务器-返回固定页面数据,1. 开发自己的静态Web服务器【附代码文档】
后端·python
小木_.1 小时前
【Python 图片下载器】一款专门为爬虫制作的图片下载器,多线程下载,速度快,支持续传/图片缩放/图片压缩/图片转换
爬虫·python·学习·分享·批量下载·图片下载器
isSamle2 小时前
使用Vue+Django开发的旅游路书应用
前端·vue.js·django
Jiude2 小时前
算法题题解记录——双变量问题的 “枚举右,维护左”
python·算法·面试
唐小旭2 小时前
python3.6搭建pytorch环境
人工智能·pytorch·python
thatway19892 小时前
AI-SoC入门:15NPU介绍
后端
陶庵看雪2 小时前
Spring Boot注解总结大全【案例详解,一眼秒懂】
java·spring boot·后端
是十一月末2 小时前
Opencv之对图片的处理和运算
人工智能·python·opencv·计算机视觉