歌曲排行榜
歌曲排行榜是按照歌曲的播放量进行排序的,用户还可以根据歌曲类型进行自定义筛选。
整个页面分为两部分:歌曲分类和歌曲列表。
歌曲排行榜在项目应用ranking中实现,首先在ranking的urls.py中分别定义ranking和rankingList。
路由定义
javascript
from django.urls import path
from .views import *
urlpatterns = [
path('', rankingView, name='ranking'),
path('.list', RankingList.as_view(), name='rankingList'),
]
我们在music的urls.py中已经为项目应用ranking定义了路由空间,因此路由ranking的路由地址为127.0.0.1:8000/ranking.html,路由的HTTP请求由视图函数rankingView接收和处理;路由rankingList的路由地址为127.0.0.1:8000/ranking.html.list,路由的HTTP请求由视图函数类RankingList接收和处理。
打开项目应用ranking的views.py,分别定义视图函数rankingView和视图函数类RankingList。
视图定义
python
from django.shortcuts import render
from index.models import *
def rankingView(request):
# 热搜歌曲
searchs = Dynamic.objects.select_related('song').order_by('-search').all()[:4]
# 歌曲分类表
labels = Label.objects.all()
# 歌曲信息表
t = request.GET.get('type', '')
if t:
dynamics = Dynamic.objects.select_related('song').filter(song__label=t).order_by('-plays').all()[:10]
else:
dynamics = Dynamic.objects.select_related('song').order_by('-plays').all()[:10]
return render(request, 'ranking.html', locals())
from django.views.generic import ListView
class RankingList(ListView):
# 设置模板的某个变量名称
context_object_name = 'dynamics'
# 设定模板文件
template_name = 'ranking.html'
# 设置变量dynamics的数据
def get_queryset(self):
# 获取请求参数
t = self.request.GET.get('type', '')
if t:
dynamics = Dynamic.objects.select_related('song').filter(song__label=t).order_by('-plays').all()[:10]
else:
dynamics = Dynamic.objects.select_related('song').order_by('-plays').all()[:10]
return dynamics
# 添加其他变量
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# 搜索歌曲
context['searchs'] = Dynamic.objects.select_related('song').order_by('-search').all()[:4]
# 所有歌曲分类
context['labels'] = Label.objects.all()
return context
视图函数rankingView和视图类RankingList实现的功能一致。
这里使用视图类处理HTTP请求,是为了让同学们了解视图类的使用方式。在上述代码中,视图类和视图函数设置了变量searchs、labels、dynamics,他们将作为模板文件ranking.html的模板上下文,每个变量的说明如下:
(1)变量searchs通过歌曲的搜索次数进行降序查询,由内置的select_related方法中实现模型Song和Dynamic的数据查询,它与视图函数index和searchs是同一个变量。
(2)变量label用于查询模型Label的全部数据。
(3)变量dynamics根据GET请求的请求参数进行数据查询。若请求参数为空,则对全部歌曲进行筛选,获取播放次数最多的前10首歌曲;若请求参数不为空,则根据参数内容进行歌曲筛选,获取播放次数最多的前10首歌曲。
模板定义
根据视图函数rankingView所生成的变量在模板文件ranking.html中编写相关的模板语法,详细代码如下:
xml
{% extends "base.html" %}
{% load static %}
{# ① #}
{% block link %}
<link rel="shortcut icon" href="{% static "favicon.ico" %}">
<link rel="stylesheet" href="{% static "css/common.css" %}">
<link rel="stylesheet" href="{% static "css/ranking.css" %}">
{% endblock %}
{% block body %}
<body>
<div class="header">
<a href="/" class="logo"><img src="{% static "image/logo.png" %}"></a>
<div class="search-box">
<form id="searchForm" action="{% url 'search' 1 %}" method="post">
{% csrf_token %}
<div class="search-keyword">
<input name="kword" type="text" class="keyword" maxlength="120">
</div>
<input id="subSerch" type="submit" class="search-button" value="搜 索" />
</form>
<div id="suggest" class="search-suggest"></div>
<div class="search-hot-words">
{% for s in searchs %}
<a target="play" href="{% url 'play' s.song.id %}" >{{ s.song.name }}</a>
{% endfor %}
</div>
</div>
</div><!--end header-->
<div class="nav-box">
<div class="nav-box-inner">
<ul class="nav clearfix">
<li><a href="{% url 'index' %}">首页</a></li>
<li><a href="{% url 'ranking' %}">歌曲排行</a></li>
<li><a href="{% url 'home' 1 %}" target="_blank">用户中心</a></li>
</ul>
</div>
</div><!--end nav-box-->
<div class="wrapper clearfix">
<!-- 左侧列表 -->
<div class="side">
{# ② #}
<!-- 子类分类排行导航 -->
<div class="side-nav">
<div class="nav-head">
<a href="{% url 'ranking' %}">所有歌曲分类</a>
</div>
<ul id="sideNav" class="cate-item">
{% for l in labels %}
<li class="computer">
<div class="main-cate">
<a href="{% url 'ranking' %}?type={{ l.id }}" class="main-title">{{ l.name }}</a>
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{# ③ #}
<!-- 左侧列表 end -->
<div class="main">
<div class="main-head-box clearfix">
<div class="main-head"><h1>歌曲排行榜</h1></div>
</div>
<table class="rank-list-table">
<tr>
<th class="cell-1">排名</th>
<th class="cell-2">封面</th>
<th class="cell-3">歌名</th>
<th class="cell-4">专辑</th>
<th class="cell-5">类型</th>
<th class="cell-6">下载量</th>
<th class="cell-6">播放量</th>
</tr>
{% for d in dynamics %}
<tr>
{%if forloop.counter < 4 %}
<td><span class="n1">{{forloop.counter}}</span></td>
{%else %}
<td><span class="n2">{{forloop.counter}}</span></td>
{%endif %}
<td>
<a href="{% url 'play' d.song.id %}" class="pic" target="play">
<img src="{{ d.song.img.url }}" width="80" height="80">
</a>
</td>
<td class="name-cell">
<h3><a href="{% url 'play' d.song.id %}" target="play" >{{d.song.name}}</a></h3>
<div class="desc">
<a href="javascript:;" class="type" >{{d.song.singer}}</a>
</div>
</td>
<td>
<div style="text-align:center;">{{d.song.album}}</div>
</td>
<td>
<div style="text-align:center;">{{d.song.label}}</div>
</td>
<td>
<div style="text-align:center;">{{d.download}}</div>
</td>
<td class="num-cell">{{d.plays}}</td>
</tr>
{% endfor %}
</table>
</div>
</div>
<script data-main="{% static "js/ranking.js" %}" src="{% static "js/require.js" %}"></script>
</body>
{% endblock %}
模板文件ranking.html重写了模板继承接口link和body,重写的网页内容已在上述代码中设置标注①、标注②、标注③,每个标注实现的功能说明如下:
(1)标注①一共实现了4个网页功能:CSS样式文件引入、网站LOGO、歌曲搜素框、热搜歌曲和网站导航栏功能。
(2)标注②遍历模板上下文labels生成歌曲分类列表,并且每个歌曲分类设置了相应的路由地址,单击某个分类即可查看该分类的歌曲排行信息。
(3)标注③遍历模板上下文dynamics生成歌曲列表,展示了每首歌曲的排名、歌曲、封面、专辑、类型、下载量和播放量,单击某一首歌曲的歌名即可进入歌曲播放页面播放当前歌曲。