django haystack 검색어 실시간 반영

hyuckhoon.ko·2021년 1월 21일
0

What I learned in first year

목록 보기
63/146

어드민에서 "브랜드" 관련 객체를 C,R,U,D하여도
브라우저 상에서 그 결과가 실시간 반영되지 않는 문제가 발생했다.

1. 첫 번째 시도

queryset evaluation


class BrandSearch(HaystackViewSet):
    index_models = [models.Brand]
    serializer_class = BrandSearchSerializer

    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        search_set = SearchQuerySet().all()
        ## force evaluate
        search_set.count()
        brand_name = request.query_params['brand_name']
        brand_set_1 = search_set.filter(text__startswith=brand_name)
        brand_set_2 = search_set.filter(text__contains=brand_name)
        brand_set = brand_set_1 | brand_set_2
        serializer = self.get_serializer(brand_set, many=True)
        return Response(serializer.data)

비권장하는 방법임을 알면서도
search_set에 저장된 쿼리셋 캐시를
강제로 evaluate했다.

이렇게 해서 문제가 해결되긴 했다.
그래도 이 상태로 유지할 수는 없는 노릇이다.



2. 두 번째 시도

@method_decorator(never_cache, name='dispatch')
class BrandSearch(HaystackViewSet):
    index_models = [models.Brand]
    serializer_class = BrandSearchSerializer

    """
    List a queryset.
    """
    def list(self, request, *args, **kwargs):
        search_set = SearchQuerySet().all()
        ## force evaluate
        #search_set.count()
        brand_name = request.query_params['brand_name']
        brand_set_1 = search_set.filter(text__startswith=brand_name)
        brand_set_2 = search_set.filter(text__contains=brand_name)
        brand_set = brand_set_1 | brand_set_2
        serializer = self.get_serializer(brand_set, many=True)
        return Response(serializer.data)

데코레이터를 적용했다.
테스틑 서버에는 현재 AWS 레디스 캐시를 사용중이며,
해당 캐시로 인해 과거의 저장된 일시적인 캐시가 실시간성을 저해하는 거라고 판단했다.

첫 번째 시도와 중복 적용하면 두 번째 시도가 효과가 있었는지 알기 어렵기 때문에 evaluate 하는 코드를 주석처리하여 진행했다.

결과는 fail
빈스톡의 캐시를 삭제하고도 추가로 진행해봤지만, 해결되지 않았다.



3. 세 번째 시도(feat.성공)

search_indexes.py 수정

class BrandIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    kor_letters = indexes.CharField(model_attr="kor_letters")
    kor_name = indexes.CharField(model_attr="kor_name")
    eng_name = indexes.CharField(model_attr="eng_name")

    autocomplete = indexes.EdgeNgramField()

    def get_model(self):
        return models.Brand

    def index_queryset(self, using=None):
    """Used when the entire index for model is updated."""
        return self.get_model().objects.all()

하다하다가 이젠 search_indexes.py를 수정했다.
그런데 그게 정답이었다.

나중에 haystack 공식문서를 자세히 읽어보니

index_queryset메소드를 제공하는데, future date가 돼야 결과가 display하게 하는 기능이라고 한다.

따라서, 아래와 같이 코드를 수정했다. index_queryset 메소드를 지웠다.

class BrandIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    kor_letters = indexes.CharField(model_attr="kor_letters")
    kor_name = indexes.CharField(model_attr="kor_name")
    eng_name = indexes.CharField(model_attr="eng_name")

    autocomplete = indexes.EdgeNgramField()

    def get_model(self):
        return models.Brand



haystack 공식문서 출처: https://django-haystack.readthedocs.io/en/master/tutorial.html#handling-data

0개의 댓글