摘要:更酷的是,我們希望搜索出來的文章也能夠按照時(shí)間熱度等各種方式進(jìn)行排序。若不為空,則檢索特定文章對(duì)象。總結(jié)本章完成了一個(gè)簡(jiǎn)單的搜索功能,這對(duì)于個(gè)人博客來說應(yīng)該夠用了。
不管是最新文章列表也好、最熱文章列表也罷,都是把所有的文章數(shù)據(jù)全部展示給了用戶。
但是如果用戶只關(guān)心某些特定類型的文章,抽取全部數(shù)據(jù)就顯得既不方便、又不效率了。
因此,給用戶提供一個(gè)搜索功能,提供給用戶感興趣的幾篇文章,就大有用處了。
準(zhǔn)備工作 邏輯盡管細(xì)節(jié)不同,但是搜索和列表有很多類似的地方:它們都是先檢索出一些文章對(duì)象,并將其展示給用戶。上一章已經(jīng)說過,代碼重復(fù)是萬惡之源,好的實(shí)踐必須把功能類似的模塊盡量復(fù)用起來。基于這個(gè)原則,我們打算繼續(xù)在原有的article_list()上添磚加瓦,讓其功能更加的強(qiáng)大。
隨著項(xiàng)目越來越龐大,又需要將功能復(fù)雜的模塊拆分成更簡(jiǎn)單的多個(gè)模塊。目前我們還不用擔(dān)心這個(gè)問題。
更酷的是,我們希望搜索出來的文章也能夠按照時(shí)間、熱度等各種方式進(jìn)行排序。因此需要構(gòu)造一個(gè)新的參數(shù)search,能夠和之前的order參數(shù)進(jìn)行聯(lián)合查詢。
GET還是POST?用戶搜索內(nèi)容時(shí)提交的文本,可以用GET請(qǐng)求提交,也可以用POST請(qǐng)求提交。根據(jù)實(shí)際的需要進(jìn)行選擇。
因?yàn)?b>order是用GET提交的,并且翻頁是GET請(qǐng)求,因此選擇GET方式提交搜索文本,可以方便地和之前的模塊結(jié)合起來。
之前我們已經(jīng)用過表單組件,通過POST請(qǐng)求提交數(shù)據(jù)。表單組件同樣也可以提交GET請(qǐng)求,只要去掉method="POST"屬性就可以了。
Q對(duì)象Model.objects.all()能夠返回表中的所有對(duì)象。
對(duì)應(yīng)的,Model.objects.filter(**kwargs)可以返回與給定參數(shù)匹配的部分對(duì)象。
還有Model.objects.exclude(**kwargs)返回與給定參數(shù)不匹配的對(duì)象
如果想對(duì)多個(gè)參數(shù)進(jìn)行查詢?cè)趺崔k?比如同時(shí)查詢文章標(biāo)題和正文內(nèi)容。這時(shí)候就需要Q對(duì)象。
視圖那么按照前面說好的,修改article_list():
article/views.py ... # 引入 Q 對(duì)象 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對(duì)象 進(jìn)行聯(lián)合搜索 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 參數(shù)重置為空 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) ...
重點(diǎn)知識(shí)如下:
新增參數(shù)search,存放需要搜索的文本。若search不為空,則檢索特定文章對(duì)象。
留意filter中Q對(duì)象的用法。Q(title__icontains=search)意思是在模型的title字段查詢,icontains是不區(qū)分大小寫的包含,中間用兩個(gè)下劃線隔開。search是需要查詢的文本。多個(gè)Q對(duì)象用管道符|隔開,就達(dá)到了聯(lián)合查詢的目的。
icontains不區(qū)分大小寫,對(duì)應(yīng)的contains區(qū)分大小寫
為什么需要search = ""語句?如果用戶沒有搜索操作,則search = request.GET.get("search")會(huì)使得search = None,而這個(gè)值傳遞到模板中會(huì)錯(cuò)誤地轉(zhuǎn)換成"None"字符串!等同于用戶在搜索“None”關(guān)鍵字,這明顯是錯(cuò)誤的。
完成本章內(nèi)容后,可以刪除此語句看看效果
除此之外還有一點(diǎn)小的代碼優(yōu)化工作:將需要重復(fù)用到order = request.GET.get("order")提取到頂部,讓模塊稍稍清爽一點(diǎn)。
模板還是修改文章列表的模板文件。
需要修改的內(nèi)容稍多,仔細(xì)一些不要看錯(cuò):
templates/article/list.html ...{% if search %} {% if articles %}"{{ search }}"的搜索結(jié)果如下:
{% else %}暫無"{{ search }}"有關(guān)的文章。
{% endif %} {% endif %} ... ... ... ... ...面包屑組件、頁碼組件都改動(dòng)了href:增加了search參數(shù)
新增搜索欄,以GET請(qǐng)求提交search參數(shù);required屬性阻止用戶提交空白文本
新增搜索提示語。好的UI必須讓用戶了解當(dāng)前的狀態(tài)
Emmm...想想也不用改動(dòng)其他東西了。
開始測(cè)試吧!
測(cè)試還是打開文章列表頁面:
出現(xiàn)了搜索欄!并且翻頁、最熱等功能一切正常。
在搜索欄中輸入“PYTHON”,結(jié)果如下:
成功將標(biāo)題或正文中含有"python"關(guān)鍵字的文章檢索出來了,并且是忽略大小寫的。點(diǎn)擊最熱可以讓檢索結(jié)果按瀏覽量排序,翻頁功能也正常工作。很好,達(dá)成了目標(biāo)!
學(xué)到這里的讀者應(yīng)該感到自豪:你用了同一個(gè)url,集成了很多種功能,展示了不同的內(nèi)容!這對(duì)新手來說其實(shí)并不容易做到。
這種方法有一個(gè)小缺點(diǎn):有的時(shí)候url中會(huì)包含像search=""(空值)這樣無意義的字符串,強(qiáng)迫癥簡(jiǎn)直不能忍。所幸這無傷大雅,通常用戶并不會(huì)關(guān)心你的url是什么樣子的,只要網(wǎng)頁美觀好用就行。總結(jié)本章完成了一個(gè)簡(jiǎn)單的搜索功能,這對(duì)于個(gè)人博客來說應(yīng)該夠用了。
更加復(fù)雜、深度定制的搜索可以借助第三方模塊,如Haystack。
另外筆者這樣實(shí)現(xiàn)搜索不一定是最優(yōu)的。相信你已經(jīng)掌握多種途徑來實(shí)現(xiàn)搜索功能了(POST請(qǐng)求?搜索專用視圖?另寫url?),盡情嘗試一番吧。
有疑問請(qǐng)?jiān)诙刨惖膫€(gè)人網(wǎng)站留言,我會(huì)盡快回復(fù)。
或Email私信我:dusaiphoto@foxmail.com
項(xiàng)目完整代碼:Django_blog_tutorial
轉(zhuǎn)載請(qǐng)注明出處。文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/42915.html
摘要:教程看到這里,你已經(jīng)學(xué)會(huì)如下內(nèi)容搭建開發(fā)環(huán)境博文管理用戶管理發(fā)表評(píng)論若干小功能搭建簡(jiǎn)單的小博客,以上的功能夠用了。教程為了起步平緩,沒有展開這方面的內(nèi)容。陌生人,祝你學(xué)業(yè)進(jìn)步事業(yè)有成歡迎常到杜賽的個(gè)人網(wǎng)站做客 教程看到這里,你已經(jīng)學(xué)會(huì)如下內(nèi)容: 搭建開發(fā)環(huán)境 博文管理 用戶管理 發(fā)表評(píng)論 若干小功能 搭建簡(jiǎn)單的小博客,以上的功能夠用了。 相信你的志向不止于此。畢竟程序員面試個(gè)個(gè)造火...
摘要:改寫視圖函數(shù)上一章我們感受了視圖的工作流程。循壞表示依次取出中的元素,命名為,并分別執(zhí)行接下來操作。即為語言,中間包裹了一個(gè)段落的文字。有疑問請(qǐng)?jiān)诙刨惖膫€(gè)人網(wǎng)站留言,我會(huì)盡快回復(fù)。 改寫視圖函數(shù) 上一章我們感受了視圖的工作流程。 為了讓視圖真正發(fā)揮作用,改寫article/views.py中的article_list視圖函數(shù): article/views.py from django...
摘要:每一篇文章的標(biāo)簽可能都不一樣,并且還可能擁有多個(gè)標(biāo)簽,這是與欄目功能不同的。列表中顯示標(biāo)簽雖然保存標(biāo)簽的功能已經(jīng)實(shí)現(xiàn)了,還得把它顯示出來才行。更多的用法請(qǐng)閱讀官方文檔總結(jié)本章學(xué)習(xí)了使用來完成標(biāo)簽功能。 標(biāo)簽是作者從文章中提取的核心詞匯,其他用戶可以通過標(biāo)簽快速了解文章的關(guān)注點(diǎn)。每一篇文章的標(biāo)簽可能都不一樣,并且還可能擁有多個(gè)標(biāo)簽,這是與欄目功能不同的。 好在標(biāo)簽功能也有優(yōu)秀的三方庫:D...
摘要:語法支持再次打開文件,在文件的最后添加指明了使用語法標(biāo)記,做了兩個(gè)拓展,其中表示支持語法高亮,包含的特性請(qǐng)參見相關(guān)文檔。語法高亮支持注意這一步必須在安裝完主題之后。 目前網(wǎng)上搭建個(gè)人博客的方案很多,雖然使用諸如 Wordpress ( PHP )、Hexo ( Node.js ) 等可以方便快速地搭建一款功能齊全的高性能個(gè)人博客,但是本文將嘗試一種更為小眾化的方案 —— 一款基于 dj...
摘要:而文章分類一個(gè)重要的途徑就是設(shè)置欄目。修改文件欄目的欄目標(biāo)題創(chuàng)建時(shí)間文章欄目的一對(duì)多外鍵欄目的有兩個(gè)字段,名稱和創(chuàng)建日期。修改文章的欄目功能,也就完成了。對(duì)個(gè)人博客來說,欄目數(shù)據(jù)的變動(dòng)通常是很少的。 博客的文章類型通常不止一種:有時(shí)候你會(huì)寫高深莫測(cè)的技術(shù)文章,有時(shí)候又純粹只記錄一下當(dāng)天的心情。 因此對(duì)文章的分類就顯得相當(dāng)?shù)闹匾耍确奖悴┲鲗?duì)文章進(jìn)行分類歸檔,也方便用戶有針對(duì)性的閱讀。...
閱讀 3066·2021-11-23 09:51
閱讀 1046·2021-09-02 15:21
閱讀 3012·2019-08-30 13:56
閱讀 1835·2019-08-29 14:12
閱讀 715·2019-08-29 13:53
閱讀 1671·2019-08-29 11:32
閱讀 1334·2019-08-29 11:25
閱讀 1498·2019-08-28 17:51