Django 博客实现简单的全文搜索的示例代码
作者:HelloGitHub-追梦人物
文中所涉及的示例代码,已同步更新到HelloGitHub-Team仓库
搜索是一个复杂的功能,但对于一些简单的搜索任务,我们可以使用DjangoModel层提供的一些内置方法来完成。现在我们来为我们的博客提供一个简单的搜索功能。
概述
博客文章通常包含标题和正文两个部分。当用户输入某个关键词进行搜索后,我们希望为用户显示标题和正文中含有被搜索关键词的全部文章。整个搜索的过程如下:
- 用户在搜素框中输入搜索关键词,假设为“django”,然后用户点击了搜索按钮提交其输入的结果到服务器。
- 服务器接收到用户输入的搜索关键词“django”后去数据库查找文章标题和正文中含有该关键词的全部文章。
- 服务器将查询结果返回给用户。
整个过程就是这样,下面来看看Django如何用实现这些过程。
将关键词提交给服务器
先来回顾一下我们的Django博客的Post(文章)模型:
blog/models.py
classPost(models.Model): #标题 title=models.CharField("标题",max_length=70) #正文 body=models.TextField("正文") #其他属性... def__str__(self): returnself.title
先看到第1步,用户在搜索框输入搜索关键词,因此我们要在博客上为用户提供一个搜索表单,HTML表单代码大概像这样:
templates/base.html
特别注意这里
用户输入了搜索关键词并点击了搜索按钮后,数据就被发送给了Django后台服务器。表单的action属性的值为{%url'blog:search'%}(虽然我们还没有写这个视图函数),表明用户提交的结果将被发送给blog应用下search视图函数对应的URL。
查找含有搜索关键词的文章
搜索的功能将由search视图函数提供,代码写在blog/views.py里:
blog/views.py
fromdjango.contribimportmessages defsearch(request): q=request.GET.get('q') ifnotq: error_msg="请输入搜索关键词" messages.add_message(request,messages.ERROR,error_msg,extra_tags='danger') returnredirect('blog:index') post_list=Post.objects.filter(Q(title__icontains=q)|Q(body__icontains=q)) returnrender(request,'blog/index.html',{'post_list':post_list})
首先我们使用request.GET.get('q')获取到用户提交的搜索关键词。用户通过表单get方法提交的数据Django为我们保存在request.GET里,这是一个类似于Python字典的对象,所以我们使用get方法从字典里取出键q对应的值,即用户的搜索关键词。这里字典的键之所以叫q是因为我们的表单中搜索框input的name属性的值是q,如果修改了name属性的值,那么这个键的名称也要相应修改。
接下来我们做了一个小小的校验,如果用户没有输入搜索关键词而提交了表单,我们就无需执行查询,我们给给用户发一条错误提醒消息,这里使用了djangomessages应用,这在交流的桥梁:评论功能中讲过。然后将用户重定向到首页。这里的redirect函数也在那篇教程中讲过。
如果用户输入了搜索关键词,我们就通过filter方法从数据库里过滤出符合条件的所有文章。这里的过滤条件是title__icontains=q,即title中包含(contains)关键字q,前缀i表示不区分大小写。这里icontains是查询表达式(Fieldlookups),我们在之前也使用过其他类似的查询表达式,其用法是在模型需要筛选的属性后面跟上两个下划线。Django内置了很多查询表达式,建议过一遍Django官方留个印象,了解每个表达式的作用,以后碰到相关的需求就可以快速定位到文档查询其用途Fieldlookups。
此外我们这里从fromdjango.db.models中引入了一个新的东西:Q对象。Q对象用于包装查询表达式,其作用是为了提供复杂的查询逻辑。例如这里Q(title__icontains=q)|Q(body__icontains=q)表示标题(title)含有关键词q或者正文(body)含有关键词q,或逻辑使用|符号。如果不用Q对象,就只能写成title__icontains=q,body__icontains=q,这就变成标题(title)含有关键词q且正文(body)含有关键词q,就达不到我们想要的目的。
绑定URL
有了视图函数后记得把视图函数映射到相应了URL,如下。
blog/urls.py
urlpatterns=[ #其他url配置 path('search/',views.search,name='search'), ]
大功告成,在导航栏尝试输入一些关键词,看看效果吧!
当然这样的搜索功能是非常简略的,难以满足一些复杂的搜索需求。编写一个搜索引擎是一个大工程,好在django-haystack这款第三方app为我们完成了全部工作。使用它我们可以实现更加复杂的搜索功能,比如全文检索、按搜索相关度排序、关键字高亮等等类似于百度搜索的功能,功能十分强大。当然其使用也会复杂一些,下一篇教程将向大家介绍django-haystack结合Elasticsearch搜索引擎的使用方法。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。