2010-04-06 65 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