검색기능
원래 기획단계에서는 recipe라는 모델에 ingredients라는 필드가 list로 들어갈 예정이었는데 여러가지 이슈🫠로 인해 ingredients라는 모델을 새로 생성하고 fk로 연결하는 것으로 변경.
검색하는 키워드를 모두 포함하는 레시피를 찾아야 함
키워드가 A,B,C 로 들어오면
레시피라는 덩어리에서 필터링 A -> & 필터링 B -> & 필터링 C 이렇게 좁혀가는 방식을 생각했는데,
현재는 재료뭉텅이에서 필터A를 포함하는 레시피들, 필터B를 포함하는 레시피들, 필터C를 포함하는 레시피들을 찾고 여기에 중복되는 값들을 찾아야 할 듯?
# views.py
class RecipeSearchView(APIView):
def get(self, request):
""" 검색된 재료 포함하는 레시피 구한 후 object 반환 """
quart_string = request.GET['q'] # 파라미터값 추출
ingredients = quart_string.split(",") # 파라미터 값에서 ,로 분리 -> 재료 목록
recipe_ids = []
compare_ids = []
for i in range(len(ingredients)):
ingredients_list = ArticleRecipeIngredients.objects.filter(
ingredients__contains=ingredients[i].strip())
# 재료 스키마의 ingredients필드에 ingredients[i]가 포함된 데이터 필터링
# 공백이 포함되면 검색이 잘 안되서 앞뒤 공백제거도 해줌 .strip()
for j in range(len(ingredients_list)):
if i < 1:
# 첫번째 필터링 값은 바로 추가
# 레시피 아이디 append
recipe_ids.append(ingredients_list[j].article_recipe)
else:
# 2번째부터는 앞선 레시피 아이디 리스트에 포함된 경우만 비교한 리스트에 저장
if ingredients_list[j].article_recipe in recipe_ids:
compare_ids.append(ingredients_list[j].article_recipe)
if len(ingredients) > 1 and i > 0:
# 비교한 리스트를 앞선 레시피 리스트로 변경 비교 리스트 비우기
recipe_ids = compare_ids
compare_ids = []
serializer = RecipeSerializer(recipe_ids, many=True)
# 리스트 값들을 json화
return Response(serializer.data, status=status.HTTP_200_OK)
이 방법이 효과적인지는 모르겠다.
검색 기능 구현 관련해서 검색해보면 Q를 사용하던데 너무 돌아갔나 싶기도 하고...🤔
id | ingredients | article_id
1 | [돼지고기,양파,김치] | 2
위와 같은 느낌으로 생각했었는데 list 필드를 지원하는 DB가 별로 없다고 함.
튜터님께 문의해본 결과 mySQL의 경우 일정 버전 이상부터 json 타입을 지원하긴 하지만 종속성이 높아져 다른 DB로 바꾸거나 할 경우 문제가 될 수 있기 때문에 지양하는 것이 좋다고 함.
id | ingredients | article_id
1 | "돼지고기,양파,김치,파" | 2
2 | "참치,김치" | 5
어차피 텍스트를 포함하는 값을 필터링하는 거라면 그냥 통 텍스트를 저장하면 편하지 않겠냐는 의견이 나옴.
그러나 튜터님이 확장성을 고려하여 별로 모델을 생성하는 쪽을 추천하심.
그리고 만약 레시피를 수정할 경우 1번 레시피 내의 파
라는 단어를 마늘
로 수정할 경우,
"돼지고기,양마늘,김치,마늘"
이 되어버릴 가능성이 있다.
조건을 걸면 해결될 수도 있지만 그냥 분리하여 별도 테이블로 관리하기로 함.