Django2.2.7 + haystack+jieba+whoosh+drf-haystack 前后端分离搜索表问题总结

环境搭建引用可以参考
全文检索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

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 类型不一致就会报错,建议修改字段名称或或者使用多索引系统切换索引。

2.创建外键索引

由于一些搜索要求需要从表去查询主表,
模型表

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()

视图使用drf-haystack 库创建调用返回json 数据

from drf_haystack.viewsets import HaystackViewSet
from .models import TestB
from .serializers import *

class TestBSearchViewSet(HaystackViewSet):
    """
    testB搜索
    """

    index_models = [TestB]
    serializer_class = TestBIndexSerializer

序列化serializers

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')

你可能感兴趣的:(django,django,python)