57 lines
2.0 KiB
Python
57 lines
2.0 KiB
Python
from functools import reduce
|
|
|
|
from django.contrib.postgres.search import TrigramSimilarity
|
|
from django.db.models import Q
|
|
|
|
from recipes import settings
|
|
|
|
|
|
def search_recipes(queryset, params):
|
|
search_string = params.get('query', '')
|
|
search_keywords = params.getlist('keywords', [])
|
|
search_foods = params.getlist('foods', [])
|
|
search_books = params.getlist('books', [])
|
|
|
|
search_keywords_or = params.get('keywords_or', True)
|
|
search_foods_or = params.get('foods_or', True)
|
|
search_books_or = params.get('books_or', True)
|
|
|
|
search_internal = params.get('internal', None)
|
|
search_limit = params.get('limit', None)
|
|
|
|
if settings.DATABASES['default']['ENGINE'] in ['django.db.backends.postgresql_psycopg2', 'django.db.backends.postgresql']:
|
|
queryset = queryset.annotate(similarity=TrigramSimilarity('name', search_string), ).filter(Q(similarity__gt=0.1) | Q(name__unaccent__icontains=search_string)).order_by('-similarity')
|
|
else:
|
|
queryset = queryset.filter(name__icontains=search_string)
|
|
|
|
if len(search_keywords) > 0:
|
|
if search_keywords_or == 'true':
|
|
queryset = queryset.filter(keywords__id__in=search_keywords)
|
|
else:
|
|
for k in search_keywords:
|
|
queryset = queryset.filter(keywords__id=k)
|
|
|
|
if len(search_foods) > 0:
|
|
if search_foods_or == 'true':
|
|
queryset = queryset.filter(steps__ingredients__food__id__in=search_foods)
|
|
else:
|
|
for k in search_foods:
|
|
queryset = queryset.filter(steps__ingredients__food__id=k)
|
|
|
|
if len(search_books) > 0:
|
|
if search_books_or == 'true':
|
|
queryset = queryset.filter(recipebookentry__book__id__in=search_books)
|
|
else:
|
|
for k in search_books:
|
|
queryset = queryset.filter(recipebookentry__book__id=k)
|
|
|
|
queryset = queryset.distinct()
|
|
|
|
if search_internal == 'true':
|
|
queryset = queryset.filter(internal=True)
|
|
|
|
# if search_limit:
|
|
# queryset = queryset[:int(search_limit)]
|
|
|
|
return queryset
|