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()

    # 实例化Paginator
    paginator = 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()

    # 实例化Paginator
    paginator = 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())

总结

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JSON_L

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值