使用Python Django框架做一个音乐网站,
本篇主要为歌单列表、歌单详情及推荐页-歌单内容改动。
目录
可通过导航>歌单或者推荐歌单中分类跳转到歌单列表。
path('songsheet', views.songsheet, name='songsheet'),
设置接收三个参数:
分页,设置默认为1;
分类id,设置默认为精选歌单;
排序规则,最新1,最热2;
- def songsheet(request):
- """ 歌单列表 """
-
- page = request.GET.get('page', 1)
- cid = request.GET.get('cid', 1)
- # 排序 1最新 2最热
- sort = request.GET.get('sort', 1)
- if sort == 1:
- songsheets = SongSheet.objects.filter(category=cid).order_by('-addtime').all()
- else:
- songsheets = SongSheet.objects.filter(category=cid).order_by('playnum').all()
- # 实例化Paginator
- paginator = Paginator(songsheets, 20)
-
- try:
- res = paginator.page(page)
- except PageNotAnInteger:
- res = paginator.page(1)
- except EmptyPage:
- res = paginator.page(paginator.num_pages)
-
- list_num = len(res)
-
- cid = int(cid)
- # 歌单类型列表
- cates = SongCategory.categoryChoice
- cate_all = SongCategory.objects.order_by('id').all()
- return render(request, 'songsheet/index.html', locals())
说明:
对cid进行数值处理,是为了模板中if判断选中使用。
歌单类型列表在模板中的渲染分为了两部分:
1.父级类型2.所属子集类型;本来想在视图中处理为一个列表,发现模板中无法渲染,
最后只能全部传给模板,在父循环中再套一个循环判断是否为相应子集进行渲染操作。
内容如下:
- {% extends 'common/base.html' %}
- {% load static %}
-
- {% block title %}我的音乐-歌单{% endblock title %}
-
- {% block content %}
- "stylesheet" href="{% static 'css/song_sheet.css' %}">
-
- class="header">
-
"{% static 'images/logo.png' %}" class="logo" alt=""> -
-
-
- class="song_sheet">
- class="title flex_c">
- class="name">推荐歌单 class="glyphicon glyphicon-menu-down" id="dian">
-
- class="tags_out" style="display: none;">
- class="tags">
-
- {% for item in cates %}
-
- class="item_list">
-
class="tip flex_c">
- class="glyphicon glyphicon-bookmark">
- class="span_item" data-id="{{item.0}}">{{item.1}}
-
-
class="flex_c list_tags">
- {% for v in cate_all %}
- {% if v.pid == item.0 %}
- {% ifequal cid v.id %}
-
- class="item active">
- class="span_item" data-id="{{v.id}}">
-
-
- {% else %}
-
- class="item">
- class="span_item" data-id="{{v.id}}">
-
-
- {% endifequal %}
- {% endif %}
- {% endfor %}
-
-
- {% endfor %}
-
-
-
- class="list">
- {% for son in res %}
- class="item">
- class="pic_out">
- class="cover">class="play icon_play">
- class="glyphicon glyphicon-play">
-
-
"" src="/media/{{ son.cover }}" class="pic" data-src="/media/{{ son.cover }}" lazy="loaded"> -
-
class="name">
- "{{ son.name }}">
-
-
-
class="count" style="display:;">class="glyphicon glyphicon-play"> {{ son.playnum }}
-
- {% endfor %}
-
- {% if list_num < 1 %}
-
- class="nodata flex_c">
- class="inner">
-
"{% static 'images/nodata.png' %}" - alt="" class="nodata_img">
- class="tip">
暂无相关数据
-
-
- {% endif %}
-
- {% if list_num > 0 %}
-
- class="page">
- class="li-page glyphicon glyphicon-menu-left notPointer">
-
- {% for index in res.paginator.page_range %}
- {% if res.number == index %}
- {% else %}
- {% endif %}
- {% endfor %}
-
- class="glyphicon glyphicon-menu-right li-page">
-
- {% endif %}
- {% endblock content %}
- {% block styleJs %}
- {# 子页面引入js文件 #}
- // 设置类型列表初始为隐藏状态
- var tags_out = $('.tags_out');
-
- // 失去焦点事件 隐藏类型列表
- $('body').click(function(e){
- var v = $(e.target);//获取当前点击事件的元素
- var nowClass = v.attr('class');
- console.log(nowClass)
- var tans = ["span_item", "glyphicon glyphicon-menu-down", "tags_out", "item_list", "tip flex_c", "item", "item active", "flex_c list_tags"];
- console.log(tans.indexOf(nowClass))
- if(tans.indexOf(nowClass) < 0) {
- $('#dian').removeClass('glyphicon-menu-up');
- $('#dian').addClass('glyphicon-menu-down');
- tags_out.hide();
- } else {
- $('#dian').removeClass('glyphicon-menu-down');
- $('#dian').addClass('glyphicon-menu-up');
- tags_out.show();
- }
- return true;
- });
- {% endblock styleJs %}
说明:
最新、最热排序增加判断,选中效果并传递相应参数给视图,进行排序显示。
然后就是歌单类型渲染了,怎么渲染的及思路在视图处理时已做了说明,需要着重说的是,
这块费时不少:1.父子集合渲染;2.筛选条件判断选中;3.点击隐藏显示效果,需要点击相应元素打开列表,之后可以点打开元素关闭,也可以点空白处关闭。这部分功能,尝试了好几种方法,都不太理想,最后绑定body点击事件,给所点击元素做了个白名单,白名单内部的就打开歌单列表,否则就关闭。
效果:

也就是点击某个歌单后,跳转到歌单详情,展示歌单信息和所属歌单的单曲列表,有分页。
path('songsheet/song', views.songsheet_song, name='songsheet_song'),
视图处理较为简单,查询歌单信息,通过歌单与单曲外键获取相应的单曲列表;
进行分页处理,最后返回模板。
内容如下:
- def songsheet_song(request):
- """ 歌单详情-单曲列表 """
-
- id = request.GET.get('id', 1)
- page = request.GET.get('page', 1)
-
- # 查询歌单信息
- info = SongSheet.objects.filter(id=id).first()
- # 歌单单曲列表
- song_list = info.singe.all()
- # 歌单类型
- categorys = info.category.values('name')
- # 实例化Paginator
- paginator = Paginator(song_list, 20)
-
- try:
- res = paginator.page(page)
- except PageNotAnInteger:
- res = paginator.page(1)
- except EmptyPage:
- res = paginator.page(paginator.num_pages)
-
- list_num = len(res)
- return render(request, 'songsheet/song.html', locals())
模板就更简单了,直接使用的专辑详情的页面模板,改一改部分内容显示,增加一个分页。
内容如下:
- {% extends 'common/base.html' %}
- {% load static %}
-
- {% block title %}我的音乐-歌单{% endblock title %}
-
- {% block content %}
- "stylesheet" href="{% static 'css/album.css' %}">
-
- class="header">
-
"{% static 'images/logo.png' %}" class="logo" alt=""> -
-
-
- class="main_con">
- class="content">
- class="info_l">
- class="cover_out">
-
"/media/{{info.cover}}" alt="" class="cover" data-src="info.cover" lazy="loaded"> -
"{% static 'images/album_cover_record.png' %}" alt="" class="record"> -
-
class="intr">歌单简介
-
class="intr_txt">
- {{info.desc}}...
-
-
-
- class="info_r">
- "正在加载中...">
-
class="song_name">{{info.name}}
-
class="artist_name">{{info.single.name}}
-
class="song_info">
- {% for c in categorys %}
- {{c.name}}
- {% endfor %}
-
- class="btns">
-
- class="glyphicon glyphicon-play"> 立即播放
-
-
-
-
- class="glyphicon glyphicon-heart"> 收藏
-
-
-
- class="list_head head_name_album">
-
class="flex_c">
-
- class="head_num">序号
-
- class="head_name">歌曲
-
- class="head_artist">歌手
-
- class="head_time">时长
-
-
-
class="album_list">
- {% for song in res %}
-
- class="song_item flex_c">
- class="song_rank flex_c">
- class="rank_num">{{forloop.counter}}
-
- class="song_artist">
- "{{song.singler.name}}">{{song.singler.name}}
-
- class="song_time">{{song.get_song_duration}}
- class="song_opts flex_c">
- class="glyphicon glyphicon-plus">
- class="glyphicon glyphicon-play">
- class="glyphicon glyphicon-heart">
-
-
- {% endfor %}
-
-
-
- {% if info == False %}
-
- class="nodata flex_c">
- class="inner">
-
"{% static 'images/nodata.png' %}" - alt="" class="nodata_img">
- class="tip">
暂无相关数据
-
-
- {% endif %}
-
- {% if list_num > 0 %}
-
- class="page">
- class="li-page glyphicon glyphicon-menu-left notPointer">
-
- {% for index in res.paginator.page_range %}
- {% if res.number == index %}
- {% else %}
- {% endif %}
- {% endfor %}
-
- class="glyphicon glyphicon-menu-right li-page">
-
- {% endif %}
-
-
-
-
- {% endblock content %}
因为歌单功能已做完,现在可以把推荐页面的推荐歌单列表跳转改活。
增加:更多跳转到所有歌单列表;分类跳转总歌单列表相应分类;
歌单列表点击封面和歌单名称跳转到相应详情。
templates/index/index.html中推荐歌单块内容修改。
内容如下:
- class="recommend_song_sheet">
- class="list">
- {% for son in songsheets %}
-
if forloop.counter == 1 %} class="one" {% endif %}>
-
-
"/media/{{ son.cover }}" alt=""> -
-
-
-
class="name">
-
-
class="count">class="glyphicon glyphicon-play"> {{ son.playnum }}
-
-
- {% endfor %}
-
做完歌单列表,再做歌单详情有种水到渠成的快速。
关联的搜索查询,复杂的数据处理及复杂数据在模板中的渲染和选中判断,有些难度。
其他的都是一些简单的内容。