大家好,我是梓栋! 有粉丝要实现全局搜索功能不知道怎么实现,让我出一套教程,本来今天很忙的,但为了家人们,我也要挤时间出来肝一篇教程啊!
废话不多说,下面开始讲! 本教程是基于图书管理系统实现的全局搜索功能。比如在搜索框里搜索Python编程,就会出现该图书的相关信息,如下图所示,接下来我们来实现一下。
一、全局搜索功能实现
1.实现的大致流程图,如下图:
2. 路由函数url.py中写如下代码
path("search/", views.search,name="search"),
3.绘制搜索框,效果图如下:
html代码如下 :
<li class="nav-item">
<form action="{% url "librarian:search" %}" method="post">
{% csrf_token %}
<div class="card-body">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text"><i class="zmdi zmdi-book"></i></span>
</div>
<input type="text" name="search_keywords" class="form-control"/>
•
<div class="input-group-append">
<button class="btn-outline-facebook"><i
class="fa fa-search"></i></button>
•
•
</div>
</div>
</div>
</form>
</li>
4.视图函数views.py中要实现的功能
在视图函数中主要实现的QuerySet查询功能,从数据库中搜索到对象后返回到前端页面。如果还有同学对QuerySet不是很熟练的话,可以看看这篇 Django开发教程:QuerySet概念及操作。
(1)从前端中获取用户输入的关键字
search_keywords = request.POST.get("search_keywords", "")
(2)根据关键字从数据库中查询数据
if search_keywords:
books_obj_list = models.Books.objects.filter(
Q(book_name=search_keywords) | Q(author=search_keywords)) # 根据关键词搜索数据库记录,
publishers_obj_list = models.Publisher.objects.filter(
Q(name=search_keywords) | Q(address=search_keywords))
上面的方法中,我们用到了Q查询,filter()等方法中的关键字参数查询都是一起进行’and’的操作,如果需要执行更复杂的查询(例如OR语句),我们可以使用Q对象。
Q对象和 |(或)、&(与)、()(括号)、~(非) 进行联合使用
注意:Q对象和关键字混合使用的时候,关键字需要写在最后。
其实上面的代码实现的是精准查询,如果想实现模糊查询,可以使用icontains(查询时不区分大小写)进行搜索查询。
if search_keywords:
books_obj_list = models.Books.objects.filter(
Q(book_name__icontains=search_keywords) | Q(author__icontains=search_keywords)) # 根据关键词搜索数据库记录,icontains是不区分大小写
publishers_obj_list = models.Publisher.objects.filter(
Q(name__icontains=search_keywords) | Q(address=search_keywords))
(3)判断查询结果,用来控制前端页面绘制。
这里主要查询图书和出版社两个数据库表中的数据,如果能从图书数据表查询到数据就给前端页面返回True,让其绘制图书查询结果,出版社亦然。
# 如果能查询到,前端显示图书查询结果
if len(books_obj_list) != 0:
books_search_result = True
# 如果能查到,前端显示出版社查询结果
elif len(publishers_obj_list) != 0:
publishers_search_result = True
else:
error_msg = "没有查询到结果,请重新输入"
全部代码如下:
def search(request):
# 要前端中获取用户输入的关键字
search_keywords = request.POST.get("search_keywords", "")
# print(search_keywords)
if search_keywords:
books_obj_list = models.Books.objects.filter(
Q(book_name__icontains=search_keywords) | Q(author__icontains=search_keywords)) # 根据关键词搜索数据库记录,icontains是不区分大小写
publishers_obj_list = models.Publisher.objects.filter(
Q(name__icontains=search_keywords) | Q(address=search_keywords))
# 判断查询结果,用来控制前端页面绘制
if len(books_obj_list) != 0: # 如果能查询到,前端显示图书查询结果
books_search_result = True
elif len(publishers_obj_list) != 0: # 如果能查到,前端显示出版社查询结果
publishers_search_result = True
else:
error_msg = "没有查询到结果,请重新输入"
else:
error_msg = "你输入的信息错误,请重新出入"
return render(request, "search_result.html", locals())
(4)绘制查询结果页面
根据视图函数的传到前端的值来绘制页面。
- if books_search_result == True 成立,绘制图书查询结果页面
- elif publishers_search_result == True成立,绘制出版社查询结果页面
查询结果页面的全部代码如下:
{% if books_search_result == True %}
<div class="content-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="card gradient-forest">
<div class="card gradient-forest"><h4 style="color:red">图书查询结果</h4></div>
<div class="card-body text-center p-5">
<div class="table-responsive">
<div id="default-datatable_wrapper"
class="dataTables_wrapper container-fluid dt-bootstrap4">
<div class="row">
<div class="col-sm-12">
<table class="table table-dark table-striped shadow-dark"
role="grid" aria-describedby="default-datatable_info">
<thead>
<tr role="row">
<th class="sorting_asc" tabindex="0"
aria-controls="default-datatable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 50px;
font-size:17px">
<p>图书编号</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Position: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书名称</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书图片</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书类型</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>作者</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书价格</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书评分</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 101px;font-size:17px"><p>图书简介</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书销量</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书评论量</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>图书库存</p>
</th>
<th class="sorting" tabindex="0"
aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Office: activate to sort column ascending"
style="width: 100px;font-size:17px"><p>出版社</p>
</th>
</tr>
</thead>
<tbody>
{% for book_obj in books_obj_list %}
<tr role="row" class="odd">
<td class="sorting_1"
style="width: 50px">{{ book_obj.book_num }}</td>
<td>{{ book_obj.book_name }}</td>
<!-- 使用弹框来显示图书的详情-->
<td>
<a href="{% static book_obj.image_set.first.img_address.name %}"
data-fancybox="group2"
data-caption="{{ book_obj.book_name }}">
<img src="{% static book_obj.image_set.first.img_address.name %}"
alt="lightbox"
class="lightbox-thumb img-thumbnail">
</a>
</td>
<td>{{ book_obj.book_type }}</td>
<td>{{ book_obj.author }}</td>
<td>{{ book_obj.book_price }}</td>
<td>{{ book_obj.book_score }}</td>
<td style="width: 100px">
<div style="width:100px;overflow: hidden;text-overflow: ellipsis">{{ book_obj.book_description }}</div>
</td>
<td>{{ book_obj.book_sales }}</td>
<td>{{ book_obj.comment_nums }}</td>
<td>{{ book_obj.book_inventory }}</td>
<td>{{ book_obj.publisher.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div><!-- End Row-->
</div>
{% elif publishers_search_result == True %}
<div class="content-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<div class="card gradient-forest">
<div class="card gradient-forest"><h4 style="color:red">出版社查询结果</h4></div>
<div class="card-body text-center p-5">
<div class="table-responsive">
<div id="default-datatable_wrapper"
class="dataTables_wrapper container-fluid dt-bootstrap4">
</div>
<div class="row">
<div class="col-sm-12">
<table class="table table-dark table-striped shadow-dark">
<thead>
<tr role="row" class="odd">
<th class="sorting_asc" tabindex="0"
aria-controls="default-datatable" rowspan="1" colspan="1"
aria-sort="ascending"
aria-label="Name: activate to sort column descending"
style="width: 140px;
font-size:17px">
<p>出版社id</p>
</th>
<th class="sorting" tabindex="0" aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Name: activate to sort column descending"
style="width: 225px;font-size:17px"><p>出版社</p>
</th>
<th class="sorting" tabindex="0" aria-controls="default-datatable"
rowspan="1" colspan="1"
aria-label="Name: activate to sort column descending"
style="width: 101px;font-size:17px"><p>出版社地址</p>
</th>
</tr>
</thead>
<tbody>
{% for publisher_obj in publishers_obj_list %}
<tr role="row" class="odd">
<td class="sorting_1">{{ publisher_obj.id }}</td>
<td>{{ publisher_obj.name }}</td>
<td>{{ publisher_obj.address }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% else %}
<div id="wrapper">
<div class="container" style="margin: 20px 310px">
<div class="row">
<div class="col-md-12">
<div class="text-center error-pages">
<h1 class="error-title text-white"> 404</h1>
<h2 class="error-sub-title text-white">查询失败</h2>
<p class="error-message text-white text-uppercase">{{ error_msg }}</p>
<div class="mt-4">
<a href="/librarian/index/" class="btn btn-info btn-round shadow-info m-1">返回主页</a>
{# <a href="javascript:void();" class="btn btn-info btn-round m-1">Previous Page </a>#}
</div>
<hr class="w-50 border-light-2">
<hr class="w-50 border-light-2">
</div>
</div>
</div>
</div>
</div><!--wrapper-->
{% endif %}
查询图书结果页面,如下图所示
查询出版社结果页面,如下图所示
如果查询失败的页面效果,如下图所示。
二、解决侧边栏的问题
要实现如下图所示的侧边栏的功能其实也很简单,就是ul 标签下的li标签中嵌套ul...li标签和a标签来实现的。
实现上图效果代码如下:
<ul class="sidebar-menu do-nicescrol">
<li class="sidebar-header">主导航</li>
<li>
<a href="index.html" class="waves-effect">
<i class="zmdi zmdi-view-dashboard"></i> <span>出版社管理页面</span> <i
class="fa fa-angle-left pull-right"></i>
</a>
<ul class="sidebar-submenu">
<li><a href="/librarian/add_publisher"><i class="zmdi zmdi-star-outline"></i>添加出版社</a></li>
<li><a href="/librarian/publisher_list/"><i class="zmdi zmdi-star-outline"></i>出版社列表</a></li>
</ul>
</li>
<li>
<a href="javaScript:void();" class="waves-effect">
<i class="zmdi zmdi-layers"></i>
<span>图书管理页面</span> <i class="fa fa-angle-left pull-right"></i>
</a>
<ul class="sidebar-submenu">
<li><a href="/librarian/add_book"><i class="zmdi zmdi-star-outline"></i> 添加图书</a></li>
<li><a href="/librarian/book_list"><i class="zmdi zmdi-star-outline"></i> 图书列表</a></li>
</ul>
</li>
<li>
<a href="javaScript:void();" class="waves-effect">
<i class="zmdi zmdi-gamepad"></i> <span>作者管理页面</span>
<i class="fa fa-angle-left float-right"></i>
</a>
<ul class="sidebar-submenu">
<li><a href="/librarian/add_author"><i class="zmdi zmdi-star-outline"></i> 添加作者</a></li>
<li><a href="/librarian/author_list"><i class="zmdi zmdi-star-outline"></i> 作者列表</a></li>
</ul>
</li>
<li>
<a href="javaScript:void();" class="waves-effect">
<i class="zmdi zmdi-gamepad"></i> <span>用户管理页面</span>
<i class="fa fa-angle-left float-right"></i>
</a>
<ul class="sidebar-submenu">
<li><a href="/librarian/add_user"><i class="zmdi zmdi-star-outline"></i> 添加用户</a></li>
<li><a href="/librarian/user_list"><i class="zmdi zmdi-star-outline"></i> 用户列表</a></li>
</ul>
</li>
<li class="sidebar-header">更多</li>
<li><a href="javaScript:void();" class="waves-effect"><i class="zmdi zmdi-share text-info"></i> <span>Information</span></a>
</li>
</ul>
我是梓栋,我们下期见!