diff --git a/app/app/settings.py b/app/app/settings.py index e03a5c95..db46e5d6 100644 --- a/app/app/settings.py +++ b/app/app/settings.py @@ -48,6 +48,7 @@ "general", "simple_history", "accounts", + "django_filters", ] # Add django-extensions to the installed apps if DEBUG is True diff --git a/app/app/views.py b/app/app/views.py index 19205222..7b467a7c 100644 --- a/app/app/views.py +++ b/app/app/views.py @@ -1,12 +1,11 @@ -import os +from pprint import pprint -from django.contrib.postgres.search import SearchHeadline, SearchQuery, SearchRank -from django.core.paginator import Paginator from django.db.models import Count from django.http import HttpResponse from django.shortcuts import get_object_or_404, render from django.utils.translation import gettext as _ +from general.filters import DocumentFileFilter from general.models import DocumentFile, Institution, Language, Project, Subject @@ -230,79 +229,197 @@ def institutions(request): def search(request): - # project_subjects = Subject.objects.all() - if request.method == "POST": - search_request = request.POST.get("search") - subjects_request = request.POST.get("subjects") - - print(search_request) - print(subjects_request) - - project_subjects = Subject.objects.all() - documents = DocumentFile.objects.all() - - selected_subjects = [] - if search_request: - queue = SearchQuery(search_request) - search_headline = SearchHeadline("document_data", queue) - - documents = ( - DocumentFile.objects.annotate(rank=SearchRank("search_vector", queue)) - .select_related("institution") - .annotate(search_headline=search_headline) - .filter(search_vector=queue) - # .only('title', 'description', 'institution__name','institution__abbreviation', 'search_headline', 'rank') - .order_by("-rank") - ) - - # if subjects_request: - # # Split the subjects_request string into a list of subject IDs - # subject_ids = subjects_request.split(',') - # print(subject_ids) - # # Filter documents by those subject IDs - # documents = documents.filter(subjects__id__in=subject_ids).distinct() - - if subjects_request: - subject_ids = subjects_request.split(",") - documents = documents.filter(subjects__id__in=subject_ids).distinct() - - # Query the Subject model to get the names of the selected subjects - selected_subjects = Subject.objects.filter(id__in=subject_ids).values_list( - "name", flat=True - ) + # form = DocumentFileSearchForm(request.GET or None) + pprint(request.GET) + f = DocumentFileFilter(request.GET, queryset=DocumentFile.objects.all()) - else: - documents = None - - # Create a Paginator instance with the documents and the number of items per page - paginator = Paginator(documents, 10) if documents else None # Show 10 documents per page - - # Get the page number from the request's GET parameters - page_number = request.GET.get("page") - - # Use the get_page method to get the Page object for that page number - page_obj = paginator.get_page(page_number) if paginator else None - - feature_flag = os.getenv("FEATURE_FLAG", False) - - template = "app/search.html" - context = { - "search": search_request, - "documents": page_obj, - "project_subjects": project_subjects, - "selected_subjects": selected_subjects, - "current_page": "search", - "document_count": len(documents) if documents else 0, - "feature_flag": feature_flag, - } + context = { + "filter": f, + } + template = "app/search.html" - return render(request, template_name=template, context=context) + return render(request, template_name=template, context=context) - else: - feature_flag = os.getenv("FEATURE_FLAG", False) - template = "app/search.html" - context = { - "project_subjects": Subject.objects.all(), - "feature_flag": feature_flag, - } - return render(request, template_name=template, context=context) + # if form.is_valid(): + # query = form.cleaned_data.get('query') + # subjects = form.cleaned_data.get('subjects') + # brands = form.cleaned_data.get('languages') + + # context = { + # # 'form': form, + # # "project_subjects": Subject.objects.all(), + # # "project_languages": Language.objects.all(), + # # "feature_flag": feature_flag, + # # } + + # else: + # f = DocumentFileFilter(request.GET, queryset=DocumentFile.objects.all()) + # + # context = { + # "filter": f.qs, + # } + # template = "app/search.html" + # + # return render(request, template_name=template, context=context) + + +# if request.method == "POST": +# search_request = request.POST.get("search") +# subjects_request = request.POST.getlist("subjects[]") # Adjusted to handle multiple selections +# languages_request = request.POST.getlist("languages[]") # Adjusted to handle multiple selections +# +# project_subjects = Subject.objects.all() +# project_languages = Language.objects.all() +# documents = DocumentFile.objects.all() +# +# selected_subjects = [] +# selected_languages = [] +# +# if search_request: +# queue = SearchQuery(search_request) +# search_headline = SearchHeadline("document_data", queue) +# +# documents = ( +# DocumentFile.objects.annotate(rank=SearchRank("search_vector", queue)) +# .select_related("institution") +# .annotate(search_headline=search_headline) +# .filter(search_vector=queue) +# .order_by("-rank") +# ) +# +# if subjects_request: +# subject_ids = subjects_request +# documents = documents.filter(subjects__id__in=subject_ids).distinct() +# +# # Query the Subject model to get the names of the selected subjects +# selected_subjects = Subject.objects.filter(id__in=subject_ids).values_list("name", flat=True) +# +# print(selected_subjects) +# +# if languages_request: +# subject_ids = subjects_request +# documents = documents.filter(subjects__id__in=subject_ids).distinct() +# +# # Query the Subject model to get the names of the selected subjects +# selected_languages = Subject.objects.filter(id__in=subject_ids).values_list("name", flat=True) +# +# print(selected_languages) +# +# paginator = Paginator(documents, 10) if documents else None +# page_number = request.GET.get("page") +# page_obj = paginator.get_page(page_number) if paginator else None +# +# feature_flag = os.getenv("FEATURE_FLAG", False) +# +# template = "app/search.html" +# context = { +# 'form': form, +# "search": search_request, +# "documents": page_obj, +# "project_languages": project_languages, +# "project_subjects": project_subjects, +# "selected_subjects": selected_subjects, +# "current_page": "search", +# "document_count": len(documents) if documents else 0, +# "feature_flag": feature_flag, +# } +# +# return render(request, template_name=template, context=context) +# else: +# feature_flag = os.getenv("FEATURE_FLAG", False) +# template = "app/search.html" +# context = { +# 'form': form, +# "project_subjects": Subject.objects.all(), +# "project_languages": Language.objects.all(), +# "feature_flag": feature_flag, +# } +# return render(request, template_name=template, context=context) + +# def search(request): +# # project_subjects = Subject.objects.all() +# if request.method == "POST": +# search_request = request.POST.get("search") +# # subjects_request = request.POST.get("subjects") +# subjects_request = request.POST.getlist('subjects[]') +# +# # print(search_request) +# print(subjects_request) +# +# # breakpoint() +# +# project_subjects = Subject.objects.all() +# documents = DocumentFile.objects.all() +# +# selected_subjects = [] +# if search_request: +# queue = SearchQuery(search_request) +# search_headline = SearchHeadline("document_data", queue) +# +# documents = ( +# DocumentFile.objects.annotate(rank=SearchRank("search_vector", queue)) +# .select_related("institution") +# .annotate(search_headline=search_headline) +# .filter(search_vector=queue) +# # .only('title', 'description', 'institution__name','institution__abbreviation', 'search_headline', 'rank') +# .order_by("-rank") +# ) +# +# # if subjects_request: +# # # Split the subjects_request string into a list of subject IDs +# # subject_ids = subjects_request.split(',') +# # print(subject_ids) +# # # Filter documents by those subject IDs +# # documents = documents.filter(subjects__id__in=subject_ids).distinct() +# +# # if subjects_request: +# # subject_ids = subjects_request.split(",") +# # documents = documents.filter(subjects__id__in=subject_ids).distinct() +# # +# # # Query the Subject model to get the names of the selected subjects +# # selected_subjects = Subject.objects.filter(id__in=subject_ids).values_list( +# # "name", flat=True +# # ) +# +# if subjects_request: +# subject_ids = subjects_request # Already a list, no need to split +# documents = documents.filter(subjects__id__in=subject_ids).distinct() +# +# # Query the Subject model to get the names of the selected subjects +# selected_subjects = Subject.objects.filter(id__in=subject_ids).values_list("name", flat=True) +# +# else: +# documents = None +# +# # Create a Paginator instance with the documents and the number of items per page +# paginator = Paginator(documents, 10) if documents else None # Show 10 documents per page +# +# # Get the page number from the request's GET parameters +# page_number = request.GET.get("page") +# +# # Use the get_page method to get the Page object for that page number +# page_obj = paginator.get_page(page_number) if paginator else None +# +# feature_flag = os.getenv("FEATURE_FLAG", False) +# +# template = "app/search.html" +# context = { +# "search": search_request, +# "documents": page_obj, +# "project_subjects": project_subjects, +# "selected_subjects": selected_subjects, +# "current_page": "search", +# "document_count": len(documents) if documents else 0, +# "feature_flag": feature_flag, +# } +# +# return render(request, template_name=template, context=context) +# +# else: +# feature_flag = os.getenv("FEATURE_FLAG", False) +# template = "app/search.html" +# context = { +# "project_subjects": Subject.objects.all(), +# "feature_flag": feature_flag, +# } +# return render(request, template_name=template, context=context) diff --git a/app/general/filters.py b/app/general/filters.py new file mode 100644 index 00000000..1a818f11 --- /dev/null +++ b/app/general/filters.py @@ -0,0 +1,34 @@ +import django_filters +from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector + +from general.models import DocumentFile + + +class DocumentFileFilter(django_filters.FilterSet): + search = django_filters.CharFilter(method="filter_search", label="Search") + + class Meta: + model = DocumentFile + fields = [ + "document_type", + "institution", + "subjects", + "languages", + ] + + def filter_search(self, queryset, name, value): + if value: + queue = SearchQuery(value) + search_vector = SearchVector("title", "description", "document_data") + # search_vector = SearchVector('document_data') + search_rank = SearchRank(search_vector, queue) + queryset = ( + queryset.annotate( + rank=search_rank, + search_vector_annotation=search_vector, # Renamed annotation to avoid conflict + ) + .select_related("institution") + .filter(search_vector_annotation=queue) + .order_by("-rank") + ) + return queryset diff --git a/app/general/forms.py b/app/general/forms.py new file mode 100644 index 00000000..72c61c73 --- /dev/null +++ b/app/general/forms.py @@ -0,0 +1,39 @@ +# forms.py +import django_filters +from django import forms + +from general.models import DocumentFile + + +class DocumentFileSearchForm(forms.Form): + title = django_filters.CharFilter(lookup_expr="iexact") + # title = django_filters.CharFilter(lookup_expr='iexact') + + class Meta: + model = DocumentFile + fields = ["subjects", "languages"] + + +# class DocumentFileSearchForm(forms.Form): +# query = forms.CharField(label='Search', max_length=255, required=False) +# +# subjects = forms.MultipleChoiceField( +# choices=[], +# required=False, +# widget=forms.SelectMultiple +# ) +# +# languages = forms.MultipleChoiceField( +# choices=[], +# required=False, +# # widget=forms.CheckboxSelectMultiple +# widget=forms.SelectMultiple +# ) +# +# def __init__(self, *args, **kwargs): +# super().__init__(*args, **kwargs) +# +# self.fields['subjects'].choices = [(cat, cat) for cat in +# Subject.objects.values_list('name', flat=True).distinct()] +# self.fields['languages'].choices = [(brand, brand) for brand in +# Language.objects.values_list('name', flat=True).distinct()] diff --git a/app/templates/app/search.html b/app/templates/app/search.html index e2336cc8..3468a4e3 100644 --- a/app/templates/app/search.html +++ b/app/templates/app/search.html @@ -9,89 +9,97 @@
{% trans "Functionality of this page coming soon" %}
#} + {# {% endif %}#} + + {% endblock content %} diff --git a/requirements.txt b/requirements.txt index f6d8f0c2..4d793de9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,3 +7,4 @@ whitenoise pillow python-magic pypdf +django-filter