2010-04-06 68 views
18

我有一個非常簡單的博客應用程序,我想添加一個非常簡單的搜索功能。在Django簡單搜索

我的模型有3個關鍵字段。

class BlogPost(models.Model): 
    title = models.CharField(max_length=100) # the title 
    intro = models.TextField(blank=True, null=True) # an extract 
    content = models.TextField(blank=True, null=True) # full post 

我不需要Google。我不想搜索評論(無論如何都在Disqus上)。我只想要一個日期排名,關鍵字過濾的職位集。

我在Google上發現的某種形式的「django」和「search」的所有內容都帶有複雜的Haystack +後端解決方案。我不需要需要。我不想在低使用率的功能上吃掉更多資源(我曾經在移植到Django之前有一個搜索框,並且它每月可能有4次搜索)。

我在這裏花時間詢問的原因(而不是僅僅寫一個凌亂的小腳本)是這已經存在於管理員。您可以設置要搜索的列,然後只需搜索即可「正常工作」。

是否有某種方式可以處理管理員提供的搜索並將其拉入到面向用戶的應用程序中?

回答

35

如果你想要一個非常簡單的搜索就可以使用icontains查找和Q object

from django.db.models import Q 
results = BlogPost.objects.filter(Q(title__icontains=your_search_query) | Q(intro__icontains=your_search_query) | Q(content__icontains=your_search_query)) 

你也應該注意到,草堆並不一定是「令人髮指的複雜」。您可以在15分鐘內用Whoosh後端設置乾草堆。

更新2016年:在版本1.10中,Django添加了a full text search support(僅PostgreSQL)。使用新的模塊到原來的問題的答案可能會是這個樣子:

from django.contrib.postgres.search import SearchVector 

results = BlogPost.objects.annotate(
    search=SearchVector('title', 'intro', 'content'), 
).filter(search=your_search_query) 

新的全文搜索模塊包含更多的功能(例如,通過相關性排序),你可以read about them in the documentation

+0

我同意,Haystack + Whoosh很容易上手。如果即使這樣做太費勁也不妨與谷歌網站搜索一起。 – 2010-04-06 13:23:42

+0

通過複雜的我不只是意味着設置。這是比這個單行程更多的代碼。我知道它有很多更好的表現,但是快速,骯髒的搜索是我目前所做的一切。謝謝! @Stijn拉着另一個搜索引擎(我會和Bing一起去,因爲他們有一個合適的服務器端API)將成爲我的下一個端口,如果髒搜索無法解決。 – Oli 2010-04-07 14:03:21

+0

謝謝你,非常有幫助。如果搜索沒有提供結果會怎樣?我們將如何生成並添加一個新的BlogPost()對象? – 2017-04-06 17:31:43

3

您將使用__search運算符。它記錄在Django QuerySet API Reference中。還有istartswith,這是一個不區分大小寫的搜索開始。

這裏的工作示例(改編自自己的Django網站):

def search(request): 
    try: 
     q = request.GET['q'] 
     posts = BlogPost.objects.filter(title__search=q) | \ 
       BlogPost.objects.filter(intro__search=q) | \ 
       BlogPost.objects.filter(content__search=q) 
     return render_to_response('search/results.html', {'posts':posts, 'q':q}) 
    except KeyError: 
     return render_to_response('search/results.html') 

注意__search只適用於MySQL和需要數據庫的直接操作添加全文索引。有關更多詳細信息,請參閱MySQL documentation

+0

的「__search」運營商只能使用特定的後端和表類型的作品支持全文索引。 – Cerin 2013-08-20 14:58:58

+0

謝謝,我已將這個包含在我的答案中。 – Frederik 2013-08-20 18:42:47

5

從Django的來源:http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/views/main.py

# Apply keyword searches. 
def construct_search(field_name): 
    if field_name.startswith('^'): 
     return "%s__istartswith" % field_name[1:] 
    elif field_name.startswith('='): 
     return "%s__iexact" % field_name[1:] 
    elif field_name.startswith('@'): 
     return "%s__search" % field_name[1:] 
    else: 
     return "%s__icontains" % field_name 

if self.search_fields and self.query: 
    for bit in self.query.split(): 
     or_queries = [models.Q(**{construct_search(str(field_name)): bit}) for field_name in self.search_fields] 
     qs = qs.filter(reduce(operator.or_, or_queries)) 
    for field_name in self.search_fields: 
     if '__' in field_name: 
      qs = qs.distinct() 
      break 

清楚,它使用數據庫選項來執行搜索。如果沒有別的,你應該能夠重用它的一些代碼。

所以說,在文檔太:http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.search_fields

全文搜索,但是,使用MySQL索引(僅當你正在使用MySQL)。

0

如果你想讓它像管理員一樣工作,你可以試試我的迷你庫Django simple search。它基本上是管理員搜索功能的一個端口。與PIP安裝它:

pip install django-simple-search 

,並用它喜歡:

from simple_search import search_filter 
from .models import BlogPost 

search_fields = ['^title', 'intro', 'content'] 
query = 'search term here' 
posts = BlogPost.objects.filter(search_filter(search_fields, query)) 

我也寫了一篇博客文章吧:https://gregbrown.co/projects/django-simple-search