环境搭建引用可以参考
全文检索django-haystack+jieba+whoosh
由于应用中需要搜索不同的表,针对不同的表去建立索引,所以要在search_indexes.py
的文件中写多个索引,
django-haystack==2.8.1
Django==2.2.7
drf-haystack==1.8.6
Whoosh==2.7.4
jieba==0.42.1
在django中使用haystack 创建索引内容报错:
ValueError: invalid literal for int() with base 10:
由于数据库设计时有一个字段同名不同类型,在建立索引时报错,
伪代码
from haystack import indexes
from .models import TestA, TestB
class TestAIndex(indexes.SearchIndex, indexes.Indexable):
"""
server索引数据模型类
"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
name = indexes.CharField(model_attr='name')
def get_model(self):
"""返回建立索引的模型类"""
return TestA
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
class TestAIndex(indexes.SearchIndex, indexes.Indexable):
"""
server索引数据模型类
"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
name = indexes.IntegerField(model_attr='name')
def get_model(self):
"""返回建立索引的模型类"""
return TestB
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
A B两个类中都设置了name 索引,但是name 类型不一致就会报错,建议修改字段名称或或者使用多索引系统切换索引。
由于一些搜索要求需要从表去查询主表,
模型表
from django.db import models
class TestA(models.Model):
name = models.CharField(max_length=20, verbose_name='名称')
note = models.CharField(max_length=200, default=0, verbose_name='备注')
class Meta:
db_table = 'testa'
verbose_name = '测试a'
verbose_name_plural = verbose_name
class TestB(models.Model):
name = models.CharField(max_length=20, verbose_name='名称')
note = models.CharField(max_length=200, default=0, verbose_name='备注')
testa = models.ForeignKey(TestA, on_delete=models.CASCADE, related_name='test_id', verbose_name='测试')
class Meta:
db_table = 'testb'
verbose_name = '测试b'
verbose_name_plural = verbose_name
@property
def test_name(self):
return self.testa.name
search_indexes.py
from haystack import indexes
from .models import TestA, TestB
class TestAIndex(indexes.SearchIndex, indexes.Indexable):
"""
server索引数据模型类
"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
name = indexes.CharField(model_attr='name')
def get_model(self):
"""返回建立索引的模型类"""
return TestA
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
class TestAIndex(indexes.SearchIndex, indexes.Indexable):
"""
server索引数据模型类
"""
text = indexes.CharField(document=True, use_template=True)
id = indexes.IntegerField(model_attr='id')
name = indexes.IntegerField(model_attr='name')
test_name = indexes.CharField(model_attr='test_name')
# 建立表TestA 中name的索引
def get_model(self):
"""返回建立索引的模型类"""
return TestB
def index_queryset(self, using=None):
"""返回要建立索引的数据查询集"""
return self.get_model().objects.all()
from drf_haystack.viewsets import HaystackViewSet
from .models import TestB
from .serializers import *
class TestBSearchViewSet(HaystackViewSet):
"""
testB搜索
"""
index_models = [TestB]
serializer_class = TestBIndexSerializer
from drf_haystack.serializers import HaystackSerializer
from .models import TestB
from .search_indexes import TestBIndex
class TestBIndexSerializer(HaystackSerializer):
"""
搜索结果数据序列化器
"""
class Meta:
index_classes = [TestBIndex]
fields = ('text','id','name','testa')