當前位置:
首頁 > 最新 > Django 完成一個簡單的搜索功能

Django 完成一個簡單的搜索功能

搜索是一個複雜的功能,但對於一些簡單的搜索任務,我們可以使用 django model 層提供的一些內置方法來完成。本文將結合 django 模型管理器的 filter 方法和 icontains 查詢表達式來實現一個簡單的搜索功能。

以博客為例,博客文章通常包含標題和正文兩個部分。當用戶輸入某個關鍵詞進行搜索後,我們希望為用戶顯示標題中含有被搜索關鍵詞的全部文章。整個搜索的過程如下:

用戶在搜素框中輸入搜索關鍵詞,假設為 「django」,然後用戶點擊了搜索按鈕提交其輸入的結果到伺服器

伺服器接收到用戶輸入的搜索關鍵詞 「django」 後去資料庫查找文章標題中含有該關鍵詞的全部文章

伺服器將查詢結果返回給用戶

整個過程就是這樣,下面來看看 django 如何用實現這些過程。

假設我們的 django 博客應用有如下的文章模型:


先看到第 1 步,用戶在搜索框輸入搜索關鍵詞,因此我們要在博客上為用戶提供一個搜索表單,html 表單代碼大概像這樣:


特別注意在 form 標籤下有一個 {% csrf_token %},這是 django 用來防禦跨站請求偽造(CSRF)攻擊的機制。如果不知道什麼是 CSRF 的話也沒有關係,只要記住在使用 django 時,前端的表單代碼里一定要加上 {% csrf_token %} 。

用戶輸入了搜索關鍵詞並點擊了搜索按鈕後,數據就被發送給了 django 後台伺服器。表單的 action 屬性的值為 /search/,表明用戶提交的結果將被發送給 /search/ 這個 URL。我們為這個 URL 綁定一個 django 視圖函數,在這個視圖函數里完成前面第 2 步提到的過程。假設我們把視圖函數的代碼寫在 blog/views.py 里:


首先我們使用 request.GET.get("q") 獲取到用戶提交的搜索關鍵詞。用戶通過表單提交的數據 django 為我們保存在 request.GET 里,這是一個類似於 Python 字典的對象,所以我們使用 get 方法從字典里取出鍵 q 對應的值,即用戶的搜索關鍵詞。這裡字典的鍵之所以叫 q 是因為我們的表單中搜索框 input 的 name 屬性的值是 q,如果修改了 name 屬性的值,那麼這個鍵的名稱也要相應修改。

接下來我們做了一個小小的校驗,如果用戶沒有輸入搜索關鍵詞而提交了表單,我們就無需執行查詢,而是渲染一個錯誤頁面提示用戶請輸入關鍵詞。如果用戶輸入了搜索關鍵詞,我們就通過 filter 方法從資料庫里過濾出符合條件的所有文章。這裡的過濾條件是 title__icontains=q,即 title 中包含(contains)關鍵字 q,前綴 i 表示不區分大小寫。這裡 icontains 是查詢表達式(Field lookups),其用法是在模型需要篩選的屬性後面跟上兩個下劃線。django 內置了很多查詢表達式,建議過一遍 django 官方留個印象,了解每個表達式的作用,以後碰到相關的需求就可以快速定位到文檔查詢其用途:Field lookups

接下來就是渲染搜索結果頁面,顯示符合搜索條件的文章列表,下面是一個模板的簡單示例:


{{ error_msg }}

{% endif %} {% for post in post_list %}

在這裡顯示文章的相應信息

{% empty %}

沒有搜索到符合條件的文章

{% endfor %}

有了視圖函數後記得把視圖函數映射到相應了 URL,前面我們表單數據提交的 URL 為 /search/,因此將視圖函數 search 綁定到該 URL 上。

大功告成!

以上示例寫的比較通用,並不是針對某個具體項目。但如果你稍微了解一點 django 的話,肯定能夠看懂文章的內容,並且稍作修改就能應用於自己的項目。如果你對 django 還不是很了解,這裡有一篇從零開始學習 django 的入門指南,能夠幫助你找到高質量的學習教程,以最快的速度入門 django 開發:django 入門學習規劃與資料推薦。

也許你前面已經學習了 django 博客開發入門教程,針對這個教程里的具體項目,我們修改上述代碼的一些細節,就可以在項目里順利運行。

首先是修改表單,打開 templates/base.html,在 header 標籤里找到搜索表單部分的代碼並修改,即添加 {% csrf_token %} 模板標籤、修改搜索框的 name 屬性和表單的 action 屬性:


... {% csrf_token %} ...

然後是編寫視圖函數:


這裡我們直接渲染了 index.html 頁面,因為這個頁面就是用來顯示文章列表的。我們對 index.html 稍作一點修改,讓它能夠顯示 error_msg。


{{ error_msg }}

{% endif %} {% for post in post_list %} ... {% empty %}

暫時還沒有發布的文章!

{% endfor %} {% endblock main %}

最後就是配置 URL:


當然這樣的搜索功能是非常簡略的,難以滿足一些複雜的搜索需求。編寫一個搜索引擎是一個大工程,好在 django-haystack 這款第三方 app 為我們完成了全部工作。使用它我們可以實現更加複雜的搜索功能,比如全文檢索、按搜索相關度排序、關鍵字高亮等等類似於百度搜索的功能,功能十分強大。


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 圓圈 的精彩文章:

TAG:圓圈 |