第十一章  音乐网站开发

  本章以音乐网站项目为例,介绍Django在实际项目开发中的应用,该网站共分为6个功能模块分别是:网站首页、歌曲排行榜、歌曲播放、歌曲点评、歌曲搜索和用户管理。

 

11.1  网站需求与设计

  当我们接到一个项目的时候,首先需要了解项目的具体需求,根据需求类型划分网站功能,并了解每个需求的业务流程。本节以音乐网站为例进行介绍,整个网站的功能分为:网站首页、歌曲排行榜、歌曲播放、歌曲搜索、歌曲点评和用户管理,各个功能说明如下:

    1、网站首页是整个网站的主界面,主要显示网站最新的动态信息以及网站的功能导航。网站动态信息以歌曲的动态为主,如热门下载、热门搜索和新歌推荐等;网站的功能导航时将其他页面的链接展示在首页上,方便用户访问浏览。

    2、歌曲排行榜是按照歌曲的播放量进行排序,用户还可以根据歌曲类型进行自定义筛选。

    3、歌曲播放是为用户提供在线试听功能,此外还提供歌曲下载、歌曲点评和相关歌曲推荐。

    4、歌曲点评是通过歌曲播放页面进入的,每条点评信息包含用户名、点评内容和点评时间。

    5、歌曲搜索是根据用户提供的关键字进行歌曲或歌手匹配查询的,搜索结果以数据列表显示在网页上。

    6、用户管理分为用户注册、登录和用户中心。用户中心包含用户信息、登录注销和歌曲播放记录。

  我们根据需求对网站的开发进行设计,首先由UI设计师根据网站需求实现网页设计图,然后由前端工程师根据网页设计图实现HTML静态页面,最后由后端工程师根据HTML静态页面实现数据库构建和网站后台开发。根据上述网站需求,一个哦你设计了6个网站页面,其中网站页面,气宗网站首页如图所示:

音乐网站架构图案例 音乐网站功能模块图_搜索

 

 网站首页

  从网站首页的设计图可以看到,按照网站功能可以分为7个功能区,说明如下:

    1、歌曲搜索:位于网页顶端,由文本输入框和搜索按钮组成,文本输入框下面是热门搜索的歌曲。

    2、轮播图:以歌曲的封面进行轮播,单击图片可进入歌曲播放。

    3、音乐分类:位于轮播图的左边,按照歌曲的类型进行分类。

    4、热门歌曲:位于轮播图的右边,按照歌曲的播放量进行排序。

    5、新歌推荐:按照歌曲的发行时间进行排序。

    6、热门搜索:按照歌曲的搜索量进行排序。

    7、热门下载:按照歌曲的下载量进行排序。

  歌曲排行榜页面如下图:

音乐网站架构图案例 音乐网站功能模块图_django_02

 

歌曲排行榜

  从歌曲排行榜的设计图可以看到,整个页面分为两部分:歌曲分类和歌曲列表,说明如下:

    1、歌曲分类:根据歌曲类型进行歌曲筛选,筛选后的歌曲显示在歌曲列表中。

    2、歌曲列表:歌曲信息以播放次数进行降序显示,若对歌曲进行类型筛选,则对同一类型的歌曲以播放次数进行降序显示。

  歌曲播放页面如下图:

音乐网站架构图案例 音乐网站功能模块图_音乐网站架构图案例_03

 

歌曲播放

  从歌曲播放的设计图可以看到,整个页面共有4大功能:各个功能说明如下:

    1、歌曲信息:包括歌名、歌手、所属专辑、语种、流派、发行时间、歌词、歌曲封面和歌曲文件等。

    2、下载与歌曲点评:实现歌曲下载,每下载一次都会对歌曲的下载次数累加一次。单击"歌曲点评"可进入歌曲点评页面。

    3、播放列表:记录当前用户的试听记录,每播放一次都会对歌曲的播放次数累加一次。

    4、相关歌曲:根据当前歌曲的类型筛选出同一类型的其他歌曲信息。

  如下图:

音乐网站架构图案例 音乐网站功能模块图_django_04

 

 歌曲点评

  歌曲点评主要分为两部分:歌曲点评和点评信息列表,两者说明如下:

    1、歌曲点评:由文本输入框和发表按钮组成的表单,以POST的请求形式实现内容提交。

    2、点评信息列表:列出当前歌曲的点评信息,并对点评信息设置分页功能。

  歌曲搜索页面如下图:

音乐网站架构图案例 音乐网站功能模块图_音乐网站架构图案例_05

歌曲搜索

  歌曲搜索主要根据文本框的内容对歌名或歌手进行匹配查询,然后将搜索结果返回到搜索页面上,其说明如下:

    1、若文本框的内容为空,则默认返回前50首最新发行的歌曲。

    2、若文本框的内容不为空,则从歌曲的歌名或歌手进行匹配查询,查询结果以歌曲的发现时间进行排序。

    3、每次搜索时,若文本框的内容与歌名完全相符,则相符的歌曲将其搜索次数累加一次。

  用户中心页面如下图:

音乐网站架构图案例 音乐网站功能模块图_音乐网站架构图案例_06

 

用户中心

  用户中心需要用户登录后才能访问,该页面主要分为用户基本信息和歌曲播放记录,说明如下:

    1、用户基本信息:显示当前用户的用户头像和用户名,并设有用户退出登录链接。

    2、歌曲播放记录:播放记录来自于歌曲播放页面的播放列表,并对播放记录进行分页显示。

  用户注册和登录页面如下图:

音乐网站架构图案例 音乐网站功能模块图_数据结构_07

音乐网站架构图案例 音乐网站功能模块图_音乐网站架构图案例_08

 

   用户的注册和登录是由同一个页面实现两个不同的功能,注册和登录都是通过JavaScript脚本来控制显示的,其说明如下:

    1、用户注册:填写用户名、手机号和用户密码,其中用户名和手机号码具有唯一性,而且不能为空。

    2、用户登录:根据用户注册时所填写的手机号码或用户名实现用户登录。

 11.2  数据库设计

  从网站的需求与网站设计可以得知,歌曲信息是整个网站最为核心的数据。因此,设置网站的数据结构时,应以歌曲信息为核心数据,逐步向外扩展相关联的数据信息。

  我们将歌曲信息的数据表名为song,歌曲信息不song的数据结构如表所示:

表字段

字段类型

含义

song_id

Int类型,长度为11

主键

song_name

Varchar类型,长度为50

歌曲名称

song_singer

Varchar类型,长度为50

歌曲的演唱歌手

song_time

Varchar类型,长度为10

歌曲的播放时长

song_album

Varchar类型,长度为50

歌曲所属专辑

song_languages

Varchar类型,长度为20

歌曲的语种

song_type

Varchar类型,长度为20

歌曲的风格类型

song_release

Varchar类型,长度为20

歌曲的发行时间

song_img

Varchar类型,长度为20

歌曲封面图片路径

song_lyrics

Varchar类型,长度为50

歌曲的歌词文件路径

song_file

Varchar类型,长度为50

歌曲的文件路径

label_id

Int类型,长度为11

外键,管理歌曲分类表

歌曲信息不song的数据结构

  从表可以看到,歌曲信息表song的字段以Varchar类型定义,数据表记录了歌曲的基本信息,如歌名、歌手、时长、所属专辑、语种、流派、发现世界、歌词、歌曲封面和歌曲文件,其中歌曲封面、歌词和歌曲文件是以路径的形式记录在数据库中的。一般来说,如果网站中涉及文件的使用,数据库最好记录文件的访问路径。若将文件的内容直接写入数据库中,则会对数据库造成一定的压力,从而降低网站的响应速度。

  在歌曲信息不song的字段label_id可以知道,歌曲信息不song关联歌曲分类表,我们将歌曲分类表命名为label,歌曲分类表主要实现网站首页的音乐分类,其数据结构如下表:

 

表字段

字段类型

含义

label_id

Int类型,长度为11

主键

label_name

Varchar类型,长度为10

歌曲的分类标签

歌曲分类表的数据结构

  在网站需求中,还会涉及歌曲动态信息,因此延伸出歌曲动态表。歌曲动态表用于记录歌曲的播放次数、搜索次数和下载次数,并且与歌曲信息表song实现一对一的数据关系,也就是一首歌曲只有一条动态信息。将歌曲动态表命名为dynamic,其数据结构如表:

表字段

字段类型

含义

dynamic_id

Int类型,长度为11

主键

dynamic_

Int类型,长度为11

歌曲的播放次数

dynamic_

Int类型,长度为11

歌曲的搜索次数

dynamic_

Int类型,长度为11

歌曲的下载次数

song_id

Int类型,长度为11

外键,关联歌曲信息表

歌曲动态表的数据结构

  最后还有与歌曲信息表song相互关联的歌曲点评表,该表主要用于歌曲点评页面。从歌曲点评页面可以知道,一首歌可以有多条点评信息,说明歌曲信息表song和歌曲点评表存在一对多的数据关系。将歌曲点评表命名为comment,其数据结构如下图:

表字段

字段类型

含义

comment_id

Int类型,长度为11

主键

comment_

Varchar类型,长度为500

歌曲的点评内容

comment_

Varchar类型,长度为20

用户名

comment_

Varchar类型,长度为50

点评日期

song_id

Int类型,长度为11

外键,管理歌曲信息表

歌曲点评表的数据结构

  除此之外,还有网站的用户管理功能,用户管理功能由用户表myuser提供用户信息。用户表myuser由Django内置模型User扩展而成,其数据结构如表所示:

表字段

字段类型

含义

Id

Int类型,长度为11

主键

Password

Varchar类型,长度为128

用户密码

last_login

Datetime类型,长度为6

上次登录时间

is_superuser

Tinyint类型,长度为1

超级用户

Username

Varchar类型,长度为150

用户名

first_name

Varchar类型,长度为30

用户的名字

last_name

Varchar类型,长度为150

用户的姓氏

Email

Varchar类型,长度为254

邮箱地址

is_staff

Tinyint类型,长度为1

登录Admin权限

is_active

Tinyint类型,长度为1

用户的激活状态

date_joined

Datetime类型,长度为6

用户创建的时间

Qq

Varchar类型,长度为

用户的QQ号码

weChat

Varchar类型,长度为

用户的微信

Mobile

Varchar类型,长度为11

用户的手机号码

 

 

11.3  项目创建与配置

  我们对音乐网站的需求与设计有了大概的了解,下一步将需求与设计落实到真正开发中。我们选择Python3.7+Django2.2+MySQL+PyCharm作为网站的开发工具,开发环境是Windows操作系统。

  首先在CMD窗口下创建Django项目,项目命名为music,然后在项目music中分别创建项目应用index、ranking、play、comment、search和user,创建指令如下:

创建music项目应用
(py3_3) E:\test5\music>python manage.py startapp index

(py3_3) E:\test5\music>python manage.py startapp ranking

(py3_3) E:\test5\music>python manage.py startapp play

(py3_3) E:\test5\music>python manage.py startapp comment

(py3_3) E:\test5\music>python manage.py startapp search

(py3_3) E:\test5\music>python manage.py startapp user

  完成项目和项目应用的创建后,我们在项目music的根目录下创建文件夹templates和static,两者分别存放模板文件和静态资源文件。然后在文件夹templates中放置公用模板title_base.html,而在文件夹static目录下创建文件夹css、js、font、image、songFile、songLyric和songImg以及防止图片favicon.ico,文件夹static的目录说明如下:

    1、css是存放全网站的CSS样式的文件。

    2、js是存放全网站的JS脚本的文件。

    3、font是存放网站字体的文件。

    4、image是存放网站页面的图片。

    5、songFile是存放歌曲的文件。

    6、songLyric是存放歌词的文件。

    7、favicon.ico是网站的LOGO图片。

  项目music的目录结构是根据网站的需求与设计进行搭建的,不同的需求与设计都会导致项目的目录结构有所不同。我们打开PyCharm查看项目music的目录结构,如下图:

音乐网站架构图案例 音乐网站功能模块图_django_09

 

项目目录结构

   项目目录结构搭建完成后,下一步是对项目进行相关的配置,配置信息主要在配置文件settings.py中完成。我们对项目music的属性INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES进行相关配置,配置信息如下:

#添加新增的项目应用index、ranking、play、comment、search和user
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'index',
    'ranking',
    'user',
    'play',
    'search',
    'comment',
]

#添加中间件LocaleMiddleware
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    # 使用中文
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

#设置模板路径,在每个App中分别创建模板文件夹templates
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'),
                  os.path.join(BASE_DIR, 'index/templates'),
                  os.path.join(BASE_DIR, 'ranking/templates'),
                  os.path.join(BASE_DIR, 'user/templates'),
                  os.path.join(BASE_DIR, 'play/templates'),
                  os.path.join(BASE_DIR, 'comment/templates'),
                  ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

设置数据库连接信息,项目使用的数据库为music_db
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'music_db',
        'USER':'root',
        'PASSWORD':'root',
        'HOST':'192.168.10.100',
        'PORT':'3306',
    }
}

  任何一个项目都需要对配置属性INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES进行配置,这是一个项目的常规配置。完成项目配置后,我们接着对项目的URL进行配置。在项目的urls.py中分别对新建的App设置相应的URL地址,设置如下:

from django.contrib import admin
from django.urls import path, include

#配置URL地址信息
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('index.urls')),
    path('ranking.html', include('ranking.urls')),
    path('play/', include('play.urls')),
    path('comment/', include('comment.urls')),
    path('search/', include('search.urls')),
    path('user/', include('user.urls')),
]

  至此,音乐网站的开发环境基本上已搭建完毕。在整个项目搭建过程中,我们总结出Django开发环境的搭建流程,其说明如下:

    1、创建Django项目,可以在CMD窗口下输入创建指令或者在PyCharm下实现项目新建。

    2、创建项目的App应用,创建方式也是在CMD窗口或者PyCharm下实现。

    3、在项目的根目录下新建文件夹templates和static,分别存放模板文件和静态资源。

    4、设置项目的配置信息,由settings.py实现,常规的配置属性有INSTALLED_APPS、MIDDLEWARE、TEMPLATES和DATABASES。

    5、根据项目的App或项目的页面来设定网站的URL地址信息,由项目的urls.py实现。

 

11.4  网站首页

  网站首页是整个网站的主界面,从网站的需求设计来看,首页共实现7个功能:歌曲搜索、轮播图、音乐分类、热门歌曲、新歌推荐、热门搜索和热门下载。在项目music中,首页由项目应用index实现,我们在index中创建模板文件夹templates,在文件夹中放置模板文件index.html,如下图:

音乐网站架构图案例 音乐网站功能模块图_数据结构_10

 

index目录架构

  首页的歌曲信息应该来自于数据库,除了Django内置的数据表之外,根据项目的数据库设计得知,网站一共定义了4张数据表,为了方便管理,我们将4张数据表所对应的模型都在index的models.py中进行定义,模型定义如下:

音乐网站架构图案例 音乐网站功能模块图_音乐网站架构图案例_11

音乐网站架构图案例 音乐网站功能模块图_数据结构_12

#index/models.py
from django.db import models

# 歌曲分类表label
class Label(models.Model):
    label_id = models.AutoField('序号', primary_key=True)
    label_name = models.CharField('分类标签', max_length=10)
    def __str__(self):
        return self.label_name
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲分类'
        verbose_name_plural = '歌曲分类'

# 歌曲信息表song
class Song(models.Model):
    song_id = models.AutoField('序号', primary_key=True)
    song_name = models.CharField('歌名', max_length=50)
    song_singer = models.CharField('歌手', max_length=50)
    song_time = models.CharField('时长', max_length=10)
    song_album = models.CharField('专辑', max_length=50)
    song_languages = models.CharField('语种', max_length=20)
    song_type = models.CharField('类型', max_length=20)
    song_release = models.CharField('发行时间', max_length=20)
    song_img = models.CharField('歌曲图片', max_length=20)
    song_lyrics = models.CharField('歌词', max_length=50, default='暂无歌词')
    song_file = models.CharField('歌曲文件', max_length=50)
    label = models.ForeignKey(Label, on_delete=models.CASCADE,verbose_name='歌名分类')
    def __str__(self):
        return self.song_name
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲信息'
        verbose_name_plural = '歌曲信息'

# 歌曲动态表dynamic
class Dynamic(models.Model):
    dynamic_id = models.AutoField('序号', primary_key=True)
    song = models.ForeignKey(Song, on_delete=models.CASCADE, verbose_name='歌名')
    dynamic_plays = models.IntegerField('播放次数')
    dynamic_search = models.IntegerField('搜索次数')
    dynamic_down = models.IntegerField('下载次数')
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲动态'
        verbose_name_plural = '歌曲动态'

# 歌曲点评表comment
class Comment(models.Model):
    comment_id = models.AutoField('序号', primary_key=True)
    comment_text = models.CharField('内容', max_length=500)
    comment_user = models.CharField('用户', max_length=20)
    song = models.ForeignKey(Song, on_delete=models.CASCADE,verbose_name='歌名')
    comment_date = models.CharField('日期', max_length=50)
    class Meta:
        # 设置Admin界面的显示内容
        verbose_name = '歌曲评论'
        verbose_name_plural = '歌曲评论'

index/models.py

  上述代码定义了模型Label、Song、Dynamic和Comment,分别对应歌曲分类表label、歌曲信息表song、歌曲动态表dynamic和歌曲点评表comment。我们根据模型的定义在项目的数据库中创建相应的数据表,在PyCharm的Terminal模式下输入数据迁移指令:

(py3_3) E:\test4\music>python manage.py makemigration

#创建数据表
(py3_3) E:\test4\music>python manage.py migrate

  我们打开数据库music_db可以看到项目所有已定义的模型都能转换成相应的数据表,在数据表index_label、index_song和index_dynamic中分别添加网站开发所需的数据信息,如下图:

音乐网站架构图案例 音乐网站功能模块图_搜索_13

音乐网站架构图案例 音乐网站功能模块图_django_14

 

   数据表index_label(左)                                                                                                                     数据表index_dynamic(右)

 

音乐网站架构图案例 音乐网站功能模块图_搜索_15

 

 数据表index_song

  值得注意的是,数据表index_song的字段song_img、song_lyrics和song_file的数据分别代表静态文件夹songImg、songLyric和songFile里面的数据名。在实际的开发中,文件的存储都是采用文件服务器存放的,比如阿里云的云存储OSS和腾讯云的对象存储COS等。

  至此,网站的数据模型和数据表的数据已经部署完毕,下一步是实现网站首页的开发。网站首页主要有index的路由配置urls.py、视图views.py和模板index.html共同实现,代码如下:

#index/urls.py
from django.urls import path
from . import views
# 设置首页的URL地址信息
urlpatterns = [
    path('', views.indexView, name='index'),
]

#index/views.py
from django.shortcuts import render
from .models import *

def indexView(request):
    # 热搜歌曲
    search_song = Dynamic.objects.select_related('song').order_by('-dynamic_search').all()[:8]
    # 音乐分类
    label_list = Label.objects.all()
    # 热门歌曲
    play_hot_song = Dynamic.objects.select_related('song').order_by('-dynamic_plays').all()[:10]
    # 新歌推荐
    daily_recommendation = Song.objects.order_by('-song_release').all()[:3]
    # 热门搜索、热门下载
    search_ranking = search_song[:6]
    down_ranking = Dynamic.objects.select_related('song').order_by('-dynamic_down').all()[:6]
    all_ranking = [search_ranking, down_ranking]
    return render(request, 'index.html',locals())

  上述代码将首页的响应处理交给视图函数indexViews执行,并且将首页的URL命名为index,URL的命名可以在模板上使用Django内置的url标签生成相应的URL地址。视图函数indexViews一共执行了5此数据查询,其说明如下:

    1、search_song:通过歌曲的搜索次数进行降序查询,由Django内置的select_related方法实现模型Song和Dynamic的数据查询。

    2、label_list:查询模型Label的全部数据,数据显示在首页轮播图左侧的音乐分类中。

    3、play_host_song:由select_related方法实现模型Song和Dynamic的数据查询,查询结果以歌曲的播放次数进行降序排列,数据显示在首页轮播图右侧的热门歌曲中。

    4、daily_recommendation:以歌曲发行时间的先后顺序查询前三首歌曲的信息,数据显示在首页的新歌推荐中。

    5、all_ranking:由热门搜索和热门下载组成的列表。热门搜索的数据来自于search_song:热门下载用于获取下载次数排在前6行的歌曲信息。

  最后在模板index.html中编写模板语法,将视图函数indexViews查询所得的数据对象通过遍历的方式呈现在网页上。由于模板index.html的代码较多,此处只列出首页的功能代码,完整的模板代码可在下载资源中查看。模板index.html代码如下:

#模板index.html的功能代码
#首页的搜索框,由HTML表单实现,{%  url 'search' XXX  %}是搜索页面的地址链接
<form id="searchForm" action="{% url 'search' 1 %}" method="post" target="_blank">
        {% csrf_token %}
            <div class="search-keyword">
                <input name="kword" type="text" class="keyword" maxlength="120" placeholder="音乐节" />
            </div>
            <input id="subSerch" type="submit" class="search-button" value="搜 索" />
        </form>

#搜索框下面的热门搜索歌曲,{%  url 'play' XXX  %}是播放页面的地址链接
<div id="suggest" class="search-suggest"></div>
          <div class="search-hot-words">
            {% for song in search_song  %}
                <a target="play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }}</a>
            {% endfor  %}
          </div>

#网站导航栏
<ul class="nav clearfix">
            <li><a href="/">首页</a></li>
            <li><a href="{% url 'ranking' %}" target="_blank">歌曲排行</a></li>
            <li><a href="{% url 'home' 1 %}" target="_blank">用户中心</a></li>
        </ul>

#音乐分类,位于轮播图的左侧
<div class="category-nav-body">
                <div id="J_CategoryItems" class="category-items">
                {% for label in label_list  %}
                    <div class="item" data-index="1"><h3>
                        <a href="javascript:;">{{ label.label_name }}</a></h3>
                    </div>
                {% endfor  %}
                </div>
            </div>

#轮播图,{%  url 'play' 12  %}是播放页面的地址链接
<div id="J_FocusSlider" class="focus">
                <div id="bannerLeftBtn" class="banner_btn"></div>
                <ul class="focus-list f_w">
                    <li class="f_s"><a target="play" href="{% url 'play' 12 %}" class="layz_load" >
                        <img src="{% static '/image/datu-1.jpg' %}"  width="750" height="275"></a>
                    </li>
                    <li class="f_s"><a target="play" href="{% url 'play' 13 %}" class="layz_load" >
                        <img src="{% static '/image/datu-2.jpg' %}"  width="750" height="275"></a>
                    </li>
                </ul>
                <div id="bannerRightBtn" class="banner_btn"></div>
            </div>

#热门歌曲,位于轮播图的右侧。{{  forloop.counter  }}用于显示当前循环次数
<div class="aside">
            <h2>热门歌曲</h2>
            <ul>
                {% for song in play_hot_song  %}
                    <li><span>{{ forloop.counter }}</span>
                        <a target="play" href="{% url 'play' song.song.song_id %}" >{{ song.song.song_name }}</a>
                    </li>
                {% endfor  %}
            </ul>
        </div>

#新歌推荐
<div id="J_TodayRec" class="today-list">
                <ul>
                {% for list in daily_recommendation  %}
                    {% if forloop.first  %}
                        <li class="first">
                    {% else  %}
                        <li>
                    {% endif  %}
                    <a class="pic layz_load pic_po" target="play" href="{% url 'play' list.song_id %}" >
                        <img src="{% static "songImg/" %}{{ list.song_img }}"  ></a>
                    <div class="name">
                        <h3><a target="play" href="{% url 'play' list.song_id %}" >{{ list.song_name }}</a></h3>
                        <div class="singer"><span>{{ list.song_singer }}</span></div>
                        <div class="times">发行时间:<span>{{ list.song_release }}</span></div>
                    </div>
                    <a target="play" href="{% url 'play' list.song_id %}" class="today-buy-button" >去听听></a>
                {% endfor  %}
                </ul>
            </div>

#热门搜索和热门下载
<div id="J_Tab_Con" class="tab-container-cell">
            {% for list in all_ranking  %}
                {% if forloop.first %}
                    <ul class="product-list clearfix t_s current">
                {% else  %}
                    <ul class="product-list clearfix t_s" style="display:none;">
                {% endif  %}
                    {% for songs in list  %}
                    <li>
                        <a target="play" href="{% url 'play' songs.song.song_id %}" class="pic layz_load pic_po" >
                            <img src="{% static "songImg/" %}{{ songs.song.song_img }}" ></a>
                        <h3><a target="play" href="{% url 'play' songs.song.song_id %}" >{{ songs.song.song_name }}</a></h3>
                        <div class="singer"><span>{{ songs.song.song_singer }}</span></div>
                        {% if all_ranking|first  == list %}
                        <div class="times">搜索次数:<span>{{ songs.dynamic_search }}</span></div>
                        {% else %}
                        <div class="times">下载次数:<span>{{ songs.dynamic_down }}</span></div>
                        {% endif %}
                    </li>
                    {% endfor %}
                    </ul>
            {% endfor %}
        </div>

  从模板的功能代码可以看到,每个功能都是通过遍历的方式将视图函数传递的变量进行输出,还有部分功能在数据列举的过程中,通过判断当前循环次数来控制HTML标签的样式。为了检验首页是否正常运行,启动music项目,在浏览器上访问

 

音乐网站架构图案例 音乐网站功能模块图_django_16