python Django實(shí)戰(zhàn)之歌曲搜索功能實(shí)現(xiàn)
歌曲搜索
音樂(lè)平臺(tái)的每個(gè)網(wǎng)頁(yè)頂部都設(shè)置了歌曲搜索功能,歌曲搜索框以網(wǎng)頁(yè)表單的形式展示,并且以POST請(qǐng)求方式實(shí)現(xiàn)歌曲搜索功能,搜索結(jié)果顯示在歌曲搜索頁(yè)。歌曲搜索頁(yè)由項(xiàng)目應(yīng)用search實(shí)現(xiàn),首先在search的urls.py中定義路由search。
總路由定義
from django.conf import settings
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve
?
urlpatterns = [
path('admin/', admin.site.urls),
path('search/', include('search.urls')),
re_path('media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT}, name='media'),
]
?
搜索路由定義
from django.urls import path
from .views import *
urlpatterns = [
path('<int:page>.html', searchView, name='search'),
]
路由search設(shè)置了路由變量page,該變量代表某一頁(yè)的頁(yè)數(shù),因?yàn)楦枨乃阉鹘Y(jié)果具有不確定性,通過(guò)對(duì)搜索結(jié)果進(jìn)行分頁(yè)處理可以美化和規(guī)范網(wǎng)頁(yè)內(nèi)容。路由的HTTP請(qǐng)求由視圖函數(shù)searchView負(fù)責(zé)接收和處理,在search的views.py中定義視圖函數(shù)searchView。
視圖定義
from django.shortcuts import render, redirect
from django.core.paginator import Paginator
from django.core.paginator import EmptyPage
from django.core.paginator import PageNotAnInteger
from django.shortcuts import reverse
from django.db.models import Q, F
from index.models import *
?
?
def searchView(request, page):
if request.method == 'GET':
# 熱搜歌曲
searchs = Dynamic.objects.select_related('song').order_by('-search').all()[:6]
# 獲取搜索內(nèi)容,如果kword為空,就查詢(xún)?nèi)扛枨?
kword = request.session.get('kword', '')
if kword:
songs = Song.objects.filter(Q(name__icontains=kword) | Q(singer=kword)).order_by('-release').all()
else:
songs = Song.objects.order_by('-release').all()[:50]
# 分頁(yè)功能
paginator = Paginator(songs, 5)
try:
pages = paginator.page(page)
except PageNotAnInteger:
pages = paginator.page(1)
except EmptyPage:
pages = paginator.page(paginator.num_pages)
# 添加歌曲搜索次數(shù)
if kword:
idList = Song.objects.filter(name__icontains=kword)
for i in idList:
dynamics = Dynamic.objects.filter(song_id=i.id)
# 判斷歌曲動(dòng)態(tài)信息是否存在,若存在,則在原來(lái)的基礎(chǔ)上加1
if dynamics:
dynamics.update(search=F('search') + 1)
# 若動(dòng)態(tài)信息不存在,則創(chuàng)建新的動(dòng)態(tài)信息
else:
dynamic = Dynamic(plays=0, search=1, download=0, song_id=i.id)
dynamic.save()
return render(request, 'search.html', locals())
else:
# 處理POST請(qǐng)求,并重定向搜索頁(yè)面
request.session['kword'] = request.POST.get('kword', '')
return redirect(reverse('search', kwargs={'page': 1}))
當(dāng)視圖函數(shù)searchView接收到路由search的POST請(qǐng)求后,它將執(zhí)行歌曲搜索過(guò)程,執(zhí)行過(guò)程說(shuō)明如下:
(1)當(dāng)用戶(hù)在歌曲搜索框輸入搜索內(nèi)容并單擊“搜索”按鈕后,程序根據(jù)網(wǎng)頁(yè)表單的屬性action所指向的路由地址發(fā)送一個(gè)POST請(qǐng)求,Django接收到請(qǐng)求后,將請(qǐng)求信息交給視圖函數(shù)searchView進(jìn)行處理。
(2)如果視圖函數(shù)searchView收到一個(gè)POST請(qǐng)求,那么首先將請(qǐng)求參數(shù)kword寫(xiě)入會(huì)話Session進(jìn)行存儲(chǔ),請(qǐng)求參數(shù)kword是歌曲搜索框的搜索內(nèi)容,然后以重定向的方式訪問(wèn)歌曲搜索頁(yè)。
(3)通過(guò)重定向訪問(wèn)歌曲搜索頁(yè),等同于向歌曲搜索頁(yè)發(fā)送一個(gè)GET請(qǐng)求,視圖函數(shù)searchView首先獲取會(huì)話Session的數(shù)據(jù)判斷Session是否存在kword。
(4)如果kword存在,就以kword作為查詢(xún)條件,分別在模型Song的字段name和singer中進(jìn)行模糊查詢(xún),查詢(xún)結(jié)果根據(jù)模型字段release進(jìn)行降序排列;如果kword不存在,就查詢(xún)模型Song的所有歌曲,以模型字段release進(jìn)行降序排列,并且只獲取前50首的歌曲信息。
(5)將查詢(xún)結(jié)果進(jìn)行分頁(yè)處理,以每5首歌為一頁(yè)的方式進(jìn)行分頁(yè)。函數(shù)參數(shù)page代表某一頁(yè)的頁(yè)數(shù),它也代表路由變量page。
(6)根據(jù)搜索內(nèi)容kword查找匹配的歌曲,將符合匹配條件的歌曲進(jìn)行遍歷和判斷,如果歌曲的動(dòng)態(tài)信息存在,就對(duì)該歌曲的搜索次數(shù)累加1,否則為歌曲新建一條動(dòng)態(tài)信息,并將搜索次數(shù)設(shè)為1。
(7)最后將變量searchs和分頁(yè)對(duì)象pages傳遞給模板文件search.html,由模板引擎進(jìn)行解析并生成相應(yīng)的網(wǎng)頁(yè)內(nèi)容。
模板定義
當(dāng)模板文件search.html接收到變量searchs和分頁(yè)對(duì)象pages后,模板引擎對(duì)模板語(yǔ)法進(jìn)行解析并轉(zhuǎn)換成網(wǎng)頁(yè)內(nèi)容。變量searchs實(shí)現(xiàn)歌曲搜索框下方的熱搜歌曲,分頁(yè)對(duì)象pages實(shí)現(xiàn)當(dāng)前分頁(yè)的歌曲列表歌分頁(yè)導(dǎo)航功能。
{% extends "base.html" %}
{% load static %}
{% block link %}
<link rel="shortcut icon" href="{% static " rel="external nofollow" rel="external nofollow" rel="external nofollow" favicon.ico" %}">
<link rel="stylesheet" href="{% static " rel="external nofollow" rel="external nofollow" rel="external nofollow" css/common.css" %}">
<link rel="stylesheet" href="{% static " rel="external nofollow" rel="external nofollow" rel="external nofollow" css/search.css" %}">
{% endblock %}
?
{% block body %}
<body>
<div class="header">
<a href="/" rel="external nofollow" 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 id="kword" 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 %}" rel="external nofollow" >{{ 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' %}" rel="external nofollow" >首頁(yè)</a></li>
<li><a href="{% url 'ranking' %}" rel="external nofollow" target="_blank">歌曲排行</a></li>
<li><a href="{% url 'home' 1 %}" rel="external nofollow" target="_blank">用戶(hù)中心</a></li>
</ul>
</div>
</div><!--end nav-box-->
<!--wrapper-->
<div class="wrapper clearfix" id="wrapper">
<div class="mod_songlist">
<ul class="songlist__header">
<li class="songlist__header_name">歌曲</li>
<li class="songlist__header_author">歌手</li>
<li class="songlist__header_time">時(shí)長(zhǎng)</li>
</ul>
<ul class="songlist__list">
{% for p in pages.object_list %}
<li class="js_songlist__child">
<div class="songlist__item">
<div class="songlist__songname">
<span class="songlist__songname_txt">
<a href="{% url 'play' p.id %}" rel="external nofollow" class="js_song" target="play">{{ p.name }}</a>
</span>
</div>
<div class="songlist__artist">
<a href="javascript:;" rel="external nofollow" class="singer_name" >{{ p.singer }}</a>
</div>
<div class="songlist__time">{{ p.time }}</div>
</div>
</li>
{% endfor %}
</ul>
<div class="page-box">
<div class="pagebar" id="pageBar">
{% if pages.has_previous %}
<a href="{% url 'search' pages.previous_page_number %}" rel="external nofollow" class="prev" target="_self"><i></i>上一頁(yè)</a>
{% endif %}
?
{% for p in pages.paginator.page_range %}
{% if pages.number == p %}
<span class="sel">{{ p }}</span>
{% else %}
<a href="{% url 'search' p %}" rel="external nofollow" target="_self">{{ p }}</a>
{% endif %}
{% endfor %}
?
{% if pages.has_next %}
<a href="{% url 'search' pages.next_page_number %}" rel="external nofollow" class="next" target="_self">下一頁(yè)<i></i></a>
{% endif %}
</div>
</div>
</div>
</div>
</body>
{% endblock %}
到此這篇關(guān)于python Django實(shí)戰(zhàn)之歌曲搜索功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)python Django內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
將數(shù)據(jù)集制作成VOC數(shù)據(jù)集格式的實(shí)例
Django數(shù)據(jù)庫(kù)遷移常見(jiàn)使用方法
python之cur.fetchall與cur.fetchone提取數(shù)據(jù)并統(tǒng)計(jì)處理操作
python zip,lambda,map函數(shù)代碼實(shí)例
Python 實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)-循環(huán)隊(duì)列的操作方法
淺談Python的條件判斷語(yǔ)句if/else語(yǔ)句

