python Django实战之歌曲搜索功能实现
作者:杭州第一深情
歌曲搜索
音乐平台的每个网页顶部都设置了歌曲搜索功能,歌曲搜索框以网页表单的形式展示,并且以POST请求方式实现歌曲搜索功能,搜索结果显示在歌曲搜索页。歌曲搜索页由项目应用search实现,首先在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设置了路由变量page,该变量代表某一页的页数,因为歌曲的搜索结果具有不确定性,通过对搜索结果进行分页处理可以美化和规范网页内容。路由的HTTP请求由视图函数searchView负责接收和处理,在search的views.py中定义视图函数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] # 获取搜索内容,如果kword为空,就查询全部歌曲 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] # 分页功能 paginator = Paginator(songs, 5) try: pages = paginator.page(page) except PageNotAnInteger: pages = paginator.page(1) except EmptyPage: pages = paginator.page(paginator.num_pages) # 添加歌曲搜索次数 if kword: idList = Song.objects.filter(name__icontains=kword) for i in idList: dynamics = Dynamic.objects.filter(song_id=i.id) # 判断歌曲动态信息是否存在,若存在,则在原来的基础上加1 if dynamics: dynamics.update(search=F('search') + 1) # 若动态信息不存在,则创建新的动态信息 else: dynamic = Dynamic(plays=0, search=1, download=0, song_id=i.id) dynamic.save() return render(request, 'search.html', locals()) else: # 处理POST请求,并重定向搜索页面 request.session['kword'] = request.POST.get('kword', '') return redirect(reverse('search', kwargs={'page': 1}))
当视图函数searchView接收到路由search的POST请求后,它将执行歌曲搜索过程,执行过程说明如下:
(1)当用户在歌曲搜索框输入搜索内容并单击“搜索”按钮后,程序根据网页表单的属性action所指向的路由地址发送一个POST请求,Django接收到请求后,将请求信息交给视图函数searchView进行处理。
(2)如果视图函数searchView收到一个POST请求,那么首先将请求参数kword写入会话Session进行存储,请求参数kword是歌曲搜索框的搜索内容,然后以重定向的方式访问歌曲搜索页。
(3)通过重定向访问歌曲搜索页,等同于向歌曲搜索页发送一个GET请求,视图函数searchView首先获取会话Session的数据判断Session是否存在kword。
(4)如果kword存在,就以kword作为查询条件,分别在模型Song的字段name和singer中进行模糊查询,查询结果根据模型字段release进行降序排列;如果kword不存在,就查询模型Song的所有歌曲,以模型字段release进行降序排列,并且只获取前50首的歌曲信息。
(5)将查询结果进行分页处理,以每5首歌为一页的方式进行分页。函数参数page代表某一页的页数,它也代表路由变量page。
(6)根据搜索内容kword查找匹配的歌曲,将符合匹配条件的歌曲进行遍历和判断,如果歌曲的动态信息存在,就对该歌曲的搜索次数累加1,否则为歌曲新建一条动态信息,并将搜索次数设为1。
(7)最后将变量searchs和分页对象pages传递给模板文件search.html,由模板引擎进行解析并生成相应的网页内容。
模板定义
当模板文件search.html接收到变量searchs和分页对象pages后,模板引擎对模板语法进行解析并转换成网页内容。变量searchs实现歌曲搜索框下方的热搜歌曲,分页对象pages实现当前分页的歌曲列表歌分页导航功能。
{% 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" >首页</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">用户中心</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">时长</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>上一页</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">下一页<i></i></a> {% endif %} </div> </div> </div> </div> </body> {% endblock %}
到此这篇关于python Django实战之歌曲搜索功能实现的文章就介绍到这了,更多相关python Django内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!