Django全文搜索

Django ORM允许你执行简单的匹配操作,例如contains过滤器(或者不区分大小写的icontains)。
比如查询正文中包含django的文章

from blog.models import Post
Post.objects.filter(body__contains='framework')

但是如果希望执行复杂的搜索查询,通过相似度或加权项检索结果,则需要更强大的搜索功能。

📌虽然Django是一个与数据库无关的web框架,但它提供了一个模块,该模块支持PostgreSQL提供的部分丰富特性,不支持非PostgreSQL数据库。

Django.contrib.postgres模块提供了由PostgreSQL专享的功能。

简单查询

INSTALLED_APPS = [
	#...
    "django.contrib.postgres",

]

对单个字段进行搜索

from blog.models import Post
Post.objects.filter(body__search='django')

对多个字段进行查询

搜索Post模型的标题和正文字段

from django.contrib.postgres.search import SearchVector
from blog.models import Post

Post.objects.annotate(
		search=SearchVector('title', 'body'),
	).filter(search='django')


使用annotate并使用两个字段定义SearchVector(文章标题和正文)。

构建查询视图

创建一个自定义视图,首先需要一个搜索表单
编辑form.py,新建SearchForm表单类

from django import forms
from .models import Comment

class EmailPostForm(forms.Form):
	name = forms.CharField(max_length=25)
	email = forms.EmailField()
	to = forms.EmailField()
	comments = forms.CharField(required=False,widget=forms.Textarea)

class CommentForm(forms.ModelForm):
	class Meta:
		model = Comment
		fields = ('name','email','body')

class SearchForm(forms.Form):
	query = forms.CharField()

使用query字段让用户引入搜索词。

关于EmailPostForm和CommentForm表单的更多内容,请查看

Django发送QQ邮件-CSDN博客

Django评论系统-CSDN博客

📌注意forms.CharField后面的括号,如果没有括号不会报错

编辑views.py

from .forms import EmailPostForm,CommentForm,SearchForm
from django.contrib.postgres.search import SearchVector

def post_search(request):
    form = SearchForm()
    query = None
    results = []
    if 'query' in request.GET:
        form = SearchForm(request.Get)
        if form.is_valid():
            query = form.cleaned_data['query']
            results = Post.objects.annotate(
                search = SearchVector('title','body'),
            ).filter(search=query)
    template = "blog/post/search.html"
    context={
        'form':form,
        'query':query,
        'results':results,
    }

    return render(request,template,context)
  • 首先实例化一个表单。
  • 使用GET方法提交表单,以便生成包含查询参数URL
  • 在请求中查找query参数,检验是否提交了表单
  • 提交表单时,使用提交的GET数据实例化,并验证表单数据是否有效
  • 如果表单有效,使用自定义SearchVector实例搜索包含标题和正文字段

构建查询模版

搜索视图准备好后,创一个模版,在用户执行搜索时显示表单和结果。

在blog/post/template目录下创建search.html

```html
{% extends "blog/base.html" %}
{% block title %}Search{% endblock %}
{% block content %}
    {% if query %}
        <h1>Posts containing "{{ query }}"</h1>
        <h3>
            {% with result.cont as total_results %}
                Found {{ total_results }} result {{ total_results|pluralize }}
            {% endwith %}

        </h3>

        {% for post in results %}

            <h4>
                <a href="{{ post.get_absolute_url }}">{{post.title}}</a>
            </h4>
            {{ post.body|truncatewords:5 }}

        {% empty %}

            <p>There are no results for your query.</p>

        {% endfor%}

        <p>
            <a href="{% url 'blog:post_search' %}">Search again</a>
        </p>

    {% else %}

        <h1>Search for posts</h1>
        <form action="." method="get">{{ form.as_p }}
            <input type="submit" value="Search">
        </form>

    {% endif %}

{% endblock%}
  • 与搜索视图一样,通过查询query参数区分表单是否已提交
  • 提交前,显示表单和提交按钮
  • 提交后,显示查询查询结果总数和文章列表

post.get_absolute_url 是使用年月日为每个文章构建的URL,更多信息请查看

Django用日期URL定位详情-CSDN博客

构建查询路径

编辑urls.py

urlpatterns = [

	#...
    path('search/',views.post_search, name='post_search')

]

  • 21
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值