Django中的全文搜索(Full Text Search)框架与其它搜索引擎的比较
Django提供了内置的全文搜索框架,称为Django全文搜索(Django Full Text Search)。然而,Django全文搜索并不是一款完整的搜索引擎,而是提供了一些类似于SQL查询的功能。
相比于其它搜索引擎,Django全文搜索框架的优势在于其轻量级和易于使用。它依赖于数据库的全文搜索功能,因此需要使用支持全文搜索的数据库。目前,Django支持的数据库包括MySQL、PostgreSQL和SQLite,并且所有这些数据库都支持全文搜索。
以下是使用Django全文搜索框架实现搜索功能的示例代码:
首先,在models.py文件中,定义一个模型类,并使用django.contrib.postgres中的SearchVectorField来存储全文搜索的结果:
from django.contrib.postgres.search import SearchVectorField class Blog(models.Model): title = models.CharField(max_length=200) content = models.TextField() search_vector = SearchVectorField(null=True, blank=True) def __str__(self): return self.title def save(self, *args, **kwargs): super().save(*args, **kwargs) Blog.objects.filter(id=self.id).update(search_vector=( SearchVector('title', weight='A') + SearchVector('content', weight='B') ))
在管理员页面中,我们需要配置搜索字段和显示字段,并使用SearchQuery和SearchRank来实现搜索和排名:
from django.contrib.postgres.search import ( SearchQuery, SearchRank, SearchVector ) from django.views.generic import ListView class SearchView(ListView): template_name = 'search.html' model = Blog paginate_by = 20 def get_queryset(self): query = self.request.GET.get('q') vector = SearchVector('title', 'content') search_query = SearchQuery(query) queryset = Blog.objects.annotate( search=SearchRank(vector, search_query) ).filter(search=search_query).order_by('-search') return queryset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['query'] = self.request.GET.get('q') return context
在搜索页面中,我们可以使用Django模板语言来展示搜索结果:
{% extends 'base.html' %} {% block content %} <form method="get"> <div class="form-group"> <input type="text" name="q" class="form-control" placeholder="Search" value="{{ query }}"> </div> <button type="submit" class="btn btn-primary mb-2">Search</button> </form> <div class="list-group mt-3"> {% for blog in object_list %} <a href="{% url 'blog_detail' blog.id %}" class="list-group-item list-group-item-action"> <h5>{{ blog.title }}</h5> <p>{{ blog.content|truncatewords:30 }}</p> </a> {% empty %} <p>No results found.</p> {% endfor %} </div> {% if page_obj.has_other_pages %} <nav class="mt-4" aria-label="Page navigation"> <ul class="pagination"> {% if page_obj.has_previous %} <li class="page-item"> <a class="page-link" href="?q={{ query }}&page={{ page_obj.previous_page_number }}">Previous</a> </li> {% endif %} {% for page in page_obj.paginator.page_range %} {% if page_obj.number == page %} <li class="page-item active"> <a class="page-link" href="#">{{ page }} <span class="sr-only">(current)</span></a> </li> {% else %} <li class="page-item"> <a class="page-link" href="?q={{ query }}&page={{ page }}">{{ page }}</a> </li> {% endif %} {% endfor %} {% if page_obj.has_next %} <li class="page-item"> <a class="page-link" href="?q={{ query }}&page={{ page_obj.next_page_number }}">Next</a> </li> {% endif %} </ul> </nav> {% endif %} {% endblock %}
因此,如果我们使用上面的代码,当用户在搜索框中输入“pidancode.com”或“皮蛋编程”时,会在模型中搜索包含这些关键词的标题和内容,并按相关性排序呈现结果。
相关文章