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