第十一章 音樂網站開發
本章以音樂網站項目為例,介紹Django在實際項目開發中的應用,該網站共分為6個功能模塊分別是:網站首頁、歌曲排行榜、歌曲播放、歌曲點評、歌曲搜索和用戶管理。
11.1 網站需求與設計
當我們接到一個項目的時候,首先需要了解項目的具體需求,根據需求類型划分網站功能,並了解每個需求的業務流程。本節以音樂網站為例進行介紹,整個網站的功能分為:網站首頁、歌曲排行榜、歌曲播放、歌曲搜索、歌曲點評和用戶管理,各個功能說明如下:
1、網站首頁是整個網站的主界面,主要顯示網站最新的動態信息以及網站的功能導航。網站動態信息以歌曲的動態為主,如熱門下載、熱門搜索和新歌推薦等;網站的功能導航時將其他頁面的鏈接展示在首頁上,方便用戶訪問瀏覽。
2、歌曲排行榜是按照歌曲的播放量進行排序,用戶還可以根據歌曲類型進行自定義篩選。
3、歌曲播放是為用戶提供在線試聽功能,此外還提供歌曲下載、歌曲點評和相關歌曲推薦。
4、歌曲點評是通過歌曲播放頁面進入的,每條點評信息包含用戶名、點評內容和點評時間。
5、歌曲搜索是根據用戶提供的關鍵字進行歌曲或歌手匹配查詢的,搜索結果以數據列表顯示在網頁上。
6、用戶管理分為用戶注冊、登錄和用戶中心。用戶中心包含用戶信息、登錄注銷和歌曲播放記錄。
我們根據需求對網站的開發進行設計,首先由UI設計師根據網站需求實現網頁設計圖,然后由前端工程師根據網頁設計圖實現HTML靜態頁面,最后由后端工程師根據HTML靜態頁面實現數據庫構建和網站后台開發。根據上述網站需求,一個哦你設計了6個網站頁面,其中網站頁面,氣宗網站首頁如圖所示:
網站首頁
從網站首頁的設計圖可以看到,按照網站功能可以分為7個功能區,說明如下:
1、歌曲搜索:位於網頁頂端,由文本輸入框和搜索按鈕組成,文本輸入框下面是熱門搜索的歌曲。
2、輪播圖:以歌曲的封面進行輪播,單擊圖片可進入歌曲播放。
3、音樂分類:位於輪播圖的左邊,按照歌曲的類型進行分類。
4、熱門歌曲:位於輪播圖的右邊,按照歌曲的播放量進行排序。
5、新歌推薦:按照歌曲的發行時間進行排序。
6、熱門搜索:按照歌曲的搜索量進行排序。
7、熱門下載:按照歌曲的下載量進行排序。
歌曲排行榜頁面如下圖:
歌曲排行榜
從歌曲排行榜的設計圖可以看到,整個頁面分為兩部分:歌曲分類和歌曲列表,說明如下:
1、歌曲分類:根據歌曲類型進行歌曲篩選,篩選后的歌曲顯示在歌曲列表中。
2、歌曲列表:歌曲信息以播放次數進行降序顯示,若對歌曲進行類型篩選,則對同一類型的歌曲以播放次數進行降序顯示。
歌曲播放頁面如下圖:
歌曲播放
從歌曲播放的設計圖可以看到,整個頁面共有4大功能:各個功能說明如下:
1、歌曲信息:包括歌名、歌手、所屬專輯、語種、流派、發行時間、歌詞、歌曲封面和歌曲文件等。
2、下載與歌曲點評:實現歌曲下載,每下載一次都會對歌曲的下載次數累加一次。單擊"歌曲點評"可進入歌曲點評頁面。
3、播放列表:記錄當前用戶的試聽記錄,每播放一次都會對歌曲的播放次數累加一次。
4、相關歌曲:根據當前歌曲的類型篩選出同一類型的其他歌曲信息。
如下圖:
歌曲點評
歌曲點評主要分為兩部分:歌曲點評和點評信息列表,兩者說明如下:
1、歌曲點評:由文本輸入框和發表按鈕組成的表單,以POST的請求形式實現內容提交。
2、點評信息列表:列出當前歌曲的點評信息,並對點評信息設置分頁功能。
歌曲搜索頁面如下圖:
歌曲搜索
歌曲搜索主要根據文本框的內容對歌名或歌手進行匹配查詢,然后將搜索結果返回到搜索頁面上,其說明如下:
1、若文本框的內容為空,則默認返回前50首最新發行的歌曲。
2、若文本框的內容不為空,則從歌曲的歌名或歌手進行匹配查詢,查詢結果以歌曲的發現時間進行排序。
3、每次搜索時,若文本框的內容與歌名完全相符,則相符的歌曲將其搜索次數累加一次。
用戶中心頁面如下圖:
用戶中心
用戶中心需要用戶登錄后才能訪問,該頁面主要分為用戶基本信息和歌曲播放記錄,說明如下:
1、用戶基本信息:顯示當前用戶的用戶頭像和用戶名,並設有用戶退出登錄鏈接。
2、歌曲播放記錄:播放記錄來自於歌曲播放頁面的播放列表,並對播放記錄進行分頁顯示。
用戶注冊和登錄頁面如下圖:
用戶的注冊和登錄是由同一個頁面實現兩個不同的功能,注冊和登錄都是通過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 | 用戶的姓氏 |
Varchar類型,長度為254 | 郵箱地址 | |
is_staff | Tinyint類型,長度為1 | 登錄Admin權限 |
is_active | Tinyint類型,長度為1 | 用戶的激活狀態 |
date_joined | Datetime類型,長度為6 | 用戶創建的時間 |
Varchar類型,長度為 | 用戶的QQ號碼 | |
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的目錄結構,如下圖:
項目目錄結構
項目目錄結構搭建完成后,下一步是對項目進行相關的配置,配置信息主要在配置文件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,如下圖:
index目錄架構
首頁的歌曲信息應該來自於數據庫,除了Django內置的數據表之外,根據項目的數據庫設計得知,網站一共定義了4張數據表,為了方便管理,我們將4張數據表所對應的模型都在index的models.py中進行定義,模型定義如下:

#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 = '歌曲評論'
上述代碼定義了模型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中分別添加網站開發所需的數據信息,如下圖:
數據表index_label(左) 數據表index_dynamic(右)
數據表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 data-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 data-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 data-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 data-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項目,在瀏覽器上訪問