资讯专栏INFORMATION COLUMN

Django搭建个人博客:简单搜索博客文章

Alan / 3739人阅读

摘要:更酷的是,我们希望搜索出来的文章也能够按照时间热度等各种方式进行排序。若不为空,则检索特定文章对象。总结本章完成了一个简单的搜索功能,这对于个人博客来说应该够用了。

不管是最新文章列表也好、最热文章列表也罢,都是把所有的文章数据全部展示给了用户。

但是如果用户只关心某些特定类型的文章,抽取全部数据就显得既不方便、又不效率了。

因此,给用户提供一个搜索功能,提供给用户感兴趣的几篇文章,就大有用处了。

准备工作 逻辑

尽管细节不同,但是搜索和列表有很多类似的地方:它们都是先检索出一些文章对象,并将其展示给用户。上一章已经说过,代码重复是万恶之源,好的实践必须把功能类似的模块尽量复用起来。基于这个原则,我们打算继续在原有的article_list()上添砖加瓦,让其功能更加的强大。

随着项目越来越庞大,又需要将功能复杂的模块拆分成更简单的多个模块。目前我们还不用担心这个问题。

更酷的是,我们希望搜索出来的文章也能够按照时间、热度等各种方式进行排序。因此需要构造一个新的参数search,能够和之前的order参数进行联合查询。

GET还是POST?

用户搜索内容时提交的文本,可以用GET请求提交,也可以用POST请求提交。根据实际的需要进行选择。

因为order是用GET提交的,并且翻页是GET请求,因此选择GET方式提交搜索文本,可以方便地和之前的模块结合起来。

之前我们已经用过表单组件

,通过POST请求提交数据。表单组件同样也可以提交GET请求,只要去掉method="POST"属性就可以了。

Q对象

Model.objects.all()能够返回表中的所有对象。

对应的,Model.objects.filter(**kwargs)可以返回与给定参数匹配的部分对象。

还有Model.objects.exclude(**kwargs)返回与给定参数不匹配的对象

如果想对多个参数进行查询怎么办?比如同时查询文章标题和正文内容。这时候就需要Q对象

视图

那么按照前面说好的,修改article_list()

article/views.py

...

# 引入 Q 对象
from django.db.models import Q

def article_list(request):
    search = request.GET.get("search")
    order = request.GET.get("order")
    # 用户搜索逻辑
    if search:
        if order == "total_views":
            # 用 Q对象 进行联合搜索
            article_list = ArticlePost.objects.filter(
                Q(title__icontains=search) |
                Q(body__icontains=search)
            ).order_by("-total_views")
        else:
            article_list = ArticlePost.objects.filter(
                Q(title__icontains=search) |
                Q(body__icontains=search)
            )
    else:
        # 将 search 参数重置为空
        search = ""
        if order == "total_views":
            article_list = ArticlePost.objects.all().order_by("-total_views")
        else:
            article_list = ArticlePost.objects.all()

    paginator = Paginator(article_list, 3)
    page = request.GET.get("page")
    articles = paginator.get_page(page)
    
    # 增加 search 到 context
    context = { "articles": articles, "order": order, "search": search }
    
    return render(request, "article/list.html", context)

...

重点知识如下:

新增参数search,存放需要搜索的文本。若search不为空,则检索特定文章对象。

留意filterQ对象的用法。Q(title__icontains=search)意思是在模型的title字段查询,icontains不区分大小写的包含,中间用两个下划线隔开。search是需要查询的文本。多个Q对象用管道符|隔开,就达到了联合查询的目的。

icontains不区分大小写,对应的contains区分大小写

为什么需要search = ""语句?如果用户没有搜索操作,则search = request.GET.get("search")会使得search = None,而这个值传递到模板中会错误地转换成"None"字符串!等同于用户在搜索“None”关键字,这明显是错误的。

完成本章内容后,可以删除此语句看看效果

除此之外还有一点小的代码优化工作:将需要重复用到order = request.GET.get("order")提取到顶部,让模块稍稍清爽一点。

模板

还是修改文章列表的模板文件。

需要修改的内容稍多,仔细一些不要看错:

templates/article/list.html

...

{% if search %} {% if articles %}

"{{ search }}"的搜索结果如下:


{% else %}

暂无"{{ search }}"有关的文章。


{% endif %} {% endif %} ... ... ... ... ...

面包屑组件、页码组件都改动了href:增加了search参数

新增搜索栏,以GET请求提交search参数;required属性阻止用户提交空白文本

新增搜索提示语。好的UI必须让用户了解当前的状态

Emmm...想想也不用改动其他东西了。

开始测试吧!

测试

还是打开文章列表页面:

出现了搜索栏!并且翻页、最热等功能一切正常。

在搜索栏中输入“PYTHON”,结果如下:

成功将标题或正文中含有"python"关键字的文章检索出来了,并且是忽略大小写的。点击最热可以让检索结果按浏览量排序,翻页功能也正常工作。很好,达成了目标!

学到这里的读者应该感到自豪:你用了同一个url,集成了很多种功能,展示了不同的内容!这对新手来说其实并不容易做到。

这种方法有一个小缺点:有的时候url中会包含像search=""(空值)这样无意义的字符串,强迫症简直不能忍。所幸这无伤大雅,通常用户并不会关心你的url是什么样子的,只要网页美观好用就行。
总结

本章完成了一个简单的搜索功能,这对于个人博客来说应该够用了。

更加复杂、深度定制的搜索可以借助第三方模块,如Haystack。

另外笔者这样实现搜索不一定是最优的。相信你已经掌握多种途径来实现搜索功能了(POST请求?搜索专用视图?另写url?),尽情尝试一番吧。

有疑问请在杜赛的个人网站留言,我会尽快回复。

或Email私信我:dusaiphoto@foxmail.com

项目完整代码:Django_blog_tutorial

转载请注明出处。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42915.html

相关文章

  • Django搭建个人博客:结束和开始

    摘要:教程看到这里,你已经学会如下内容搭建开发环境博文管理用户管理发表评论若干小功能搭建简单的小博客,以上的功能够用了。教程为了起步平缓,没有展开这方面的内容。陌生人,祝你学业进步事业有成欢迎常到杜赛的个人网站做客 教程看到这里,你已经学会如下内容: 搭建开发环境 博文管理 用户管理 发表评论 若干小功能 搭建简单的小博客,以上的功能够用了。 相信你的志向不止于此。毕竟程序员面试个个造火...

    zqhxuyuan 评论0 收藏0
  • Django搭建个人博客:改写View视图

    摘要:改写视图函数上一章我们感受了视图的工作流程。循坏表示依次取出中的元素,命名为,并分别执行接下来操作。即为语言,中间包裹了一个段落的文字。有疑问请在杜赛的个人网站留言,我会尽快回复。 改写视图函数 上一章我们感受了视图的工作流程。 为了让视图真正发挥作用,改写article/views.py中的article_list视图函数: article/views.py from django...

    KaltZK 评论0 收藏0
  • Django搭建个人博客文章标签功能

    摘要:每一篇文章的标签可能都不一样,并且还可能拥有多个标签,这是与栏目功能不同的。列表中显示标签虽然保存标签的功能已经实现了,还得把它显示出来才行。更多的用法请阅读官方文档总结本章学习了使用来完成标签功能。 标签是作者从文章中提取的核心词汇,其他用户可以通过标签快速了解文章的关注点。每一篇文章的标签可能都不一样,并且还可能拥有多个标签,这是与栏目功能不同的。 好在标签功能也有优秀的三方库:D...

    Amio 评论0 收藏0
  • 使用 django-blog-zinnia 搭建个人博客

    摘要:语法支持再次打开文件,在文件的最后添加指明了使用语法标记,做了两个拓展,其中表示支持语法高亮,包含的特性请参见相关文档。语法高亮支持注意这一步必须在安装完主题之后。 目前网上搭建个人博客的方案很多,虽然使用诸如 Wordpress ( PHP )、Hexo ( Node.js ) 等可以方便快速地搭建一款功能齐全的高性能个人博客,但是本文将尝试一种更为小众化的方案 —— 一款基于 dj...

    褰辩话 评论0 收藏0
  • Django搭建个人博客:设置文章的栏目

    摘要:而文章分类一个重要的途径就是设置栏目。修改文件栏目的栏目标题创建时间文章栏目的一对多外键栏目的有两个字段,名称和创建日期。修改文章的栏目功能,也就完成了。对个人博客来说,栏目数据的变动通常是很少的。 博客的文章类型通常不止一种:有时候你会写高深莫测的技术文章,有时候又纯粹只记录一下当天的心情。 因此对文章的分类就显得相当的重要了,既方便博主对文章进行分类归档,也方便用户有针对性的阅读。...

    keelii 评论0 收藏0

发表评论

0条评论

Alan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<