Django实现音乐网站 ⒃

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

本篇主要是歌手详情页-专辑列表、专辑详情-单曲列表开发实现内容。

目录

歌手详情-专辑列表

路由设置

跳转设置

视图方法

模板内容

专辑详情-单曲列表

设置路由

视图处理并返回

模板渲染

分页优化

引入错误类型库

分页实例

总结


歌手详情-专辑列表

通过歌手名称进入歌手详情,再点击专辑可查看歌手拥有专辑列表。

路由设置

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

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

跳转设置

在歌手详情中专辑切换设置跳转链接。

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

视图方法

查询歌手信息,通过歌手外键id查询歌手所拥有的专辑列表,之后进行分页。

python 复制代码
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判断后显示无数据内容。

python 复制代码
{% 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参数即可。

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

视图处理并返回

这里就有些复杂,虽然代码比较少,还是有些技术含量的。

专辑表和单曲表是多对多的关系,查询时需要prefetch_related进行关联对应表模型。

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

模板渲染

模板渲染与歌手-单曲列表模板处理差不多,只需要注意歌手名称的显示和单曲时长显示。

内容如下:

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

分页优化

分页原来的处理比较简单,只是实现分页功能,没有处理分页范围。

这次在原来的基础上,对超出总页数和页数为空情况进行处理。

引入错误类型库

python 复制代码
from django.core.paginator import EmptyPage, PageNotAnInteger

分页实例

在try...except判断中处理分页判断并进行处理;

通过使用locals函数对传递模板的参数进行优化,不需要再单独赋值。

内容如下:

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

总结

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

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

相关推荐
AskHarries3 分钟前
不用公网 IP,把 Windows 和 Linux 服务器放进同一个局域网:Tailscale 组网实战
后端
神奇小汤圆4 分钟前
Java 的1 亿次对象创建:JVM 开启 / 关闭逃逸分析,GC 性能差距巨大
后端
tangdou3690986557 分钟前
AI真好玩系列-2分钟快速了解DeepAgents | Quick Guide to DeepAgents in 2 Minutes
前端·javascript·后端
神奇小汤圆23 分钟前
面试官:MySQL 为什么要是使用 MVCC?原理是什么?
后端
像我这样帅的人丶你还31 分钟前
Java 后端详解(五):Redis 缓存
java·后端·全栈
玉宇夕落1 小时前
别再死磕 Prompt 了!上下文工程 (Context Engineering) 的简单学习
后端
小九九的爸爸1 小时前
前端想要入门Agent开发,要具备哪些Python基础?
python·agent·ai编程
用户34232323763171 小时前
定时器与 PWM 输出详解
后端
阿耶同学2 小时前
手把手教你用 LangGraph 搭建三层嵌套 Agent 架构
python·程序员
Jason_chen2 小时前
Linux 6.2 CAN/CANFD机制详解
后端