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博客文章来源:https://www.toymoban.com/news/detail-786290.html
构建查询路径
编辑urls.py文章来源地址https://www.toymoban.com/news/detail-786290.html
urlpatterns = [
#...
path('search/',views.post_search, name='post_search')
]
到了这里,关于Django全文搜索的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!