不論是最新文章列表也好、最熱文章列表也罷,都是把全部的文章數據所有展現給了用戶。html
可是若是用戶只關心某些特定類型的文章,抽取所有數據就顯得既不方便、又不效率了。python
所以,給用戶提供一個搜索功能,提供給用戶感興趣的幾篇文章,就大有用處了。git
準備工做邏輯
article_list()
隨着項目愈來愈龐大,又須要將功能複雜的模塊拆分紅更簡單的多個模塊。目前咱們還不用擔憂這個問題。django
searchorder
GET仍是POST?
用戶搜索內容時提交的文本,能夠用GET請求提交,也能夠用POST請求提交。根據實際的須要進行選擇。優化
order
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)
...
複製代碼
重點知識以下:
Q(title__icontains=search)titleicontainssearch|search = ''search = request.GET.get('search')search = None"None"
order = request.GET.get('order')
模板
仍是修改文章列表的模板文件。
須要修改的內容稍多,仔細一些不要看錯:
templates/article/list.html
...
<div class="container">
<!-- 修改,麪包屑的href增長search參數 -->
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{% url 'article:article_list' %}?search={{ search }}">
最新
</a>
</li>
<li class="breadcrumb-item">
<a href="{% url 'article:article_list' %}?order=total_views&search={{ search }}">
最熱
</a>
</li>
</ol>
</nav>
<!-- 新增,搜索欄 -->
<div class="row">
<div class="col-auto mr-auto">
<form class="form-inline" >
<label class="sr-only">content</label>
<input type="text" class="form-control mb-2 mr-sm-2" name="search" placeholder="搜索文章..." required >
</form>
</div>
</div>
<!-- 新增,搜索提示語 -->
{% if search %}
{% if articles %}
<h4><span style="color: red">"{{ search }}"</span>的搜索結果以下:</h4>
<hr>
{% else %}
<h4>暫無<span style="color: red">"{{ search }}"</span>有關的文章。</h4>
<hr>
{% endif %}
{% endif %}
...
<!-- 修改,頁碼href增長search參數 -->
<a href="?page=1&order={{ order }}&search={{ search }}" class="btn btn-success">
...
<a href="?page={{ articles.previous_page_number }}&order={{ order }}&search={{ search }}" class="btn btn-secondary">
...
<a href="?page={{ articles.next_page_number }}&order={{ order }}&search={{ search }}" class="btn btn-secondary">
...
<a href="?page={{ articles.paginator.num_pages }}&order={{ order }}&search={{ search }}"class="btn btn-success">
...
複製代碼
searchsearchrequired
Emmm...想一想也不用改動其餘東西了。
開始測試吧!
測試仍是打開文章列表頁面:
出現了搜索欄!而且翻頁、最熱等功能一切正常。
在搜索欄中輸入「PYTHON」,結果以下:
成功將標題或正文中含有"python"關鍵字的文章檢索出來了,而且是忽略大小寫的。點擊最熱可讓檢索結果按瀏覽量排序,翻頁功能也正常工做。很好,達成了目標!
學到這裏的讀者應該感到自豪:你用了同一個url,集成了不少種功能,展現了不一樣的內容!這對新手來講其實並不容易作到。
search=''
總結
本章完成了一個簡單的搜索功能,這對於我的博客來講應該夠用了。
更加複雜、深度定製的搜索能夠藉助第三方模塊,如Haystack。
另外筆者這樣實現搜索不必定是最優的。相信你已經掌握多種途徑來實現搜索功能了(POST請求?搜索專用視圖?另寫url?),盡情嘗試一番吧。
- 有疑問請在杜賽的我的網站留言,我會盡快回復。
- 或Email私信我:dusaiphoto@foxmail.com
- 項目完整代碼:Django_blog_tutorial
轉載請註明出處。