From 4c188aca34cf09dfe94773470add6d65d300a09c Mon Sep 17 00:00:00 2001 From: Rezaul Karim Shaon Date: Fri, 29 Nov 2024 02:25:39 +0600 Subject: [PATCH 1/2] updt: publisher model name field indexed for faster search --- backend/BookShelf/settings.py | 4 +++ backend/BookShelf/utilities/pagination.py | 11 +++++++ backend/BookShelf/utilities/search.py | 33 +++++++++++++++++++ .../migrations/0003_alter_publisher_name.py | 18 ++++++++++ backend/publisher_api/models.py | 2 +- backend/publisher_api/views/v1.py | 4 +++ 6 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 backend/BookShelf/utilities/search.py create mode 100644 backend/publisher_api/migrations/0003_alter_publisher_name.py diff --git a/backend/BookShelf/settings.py b/backend/BookShelf/settings.py index 357ea14..aa85f82 100644 --- a/backend/BookShelf/settings.py +++ b/backend/BookShelf/settings.py @@ -83,6 +83,10 @@ ), 'DEFAULT_PAGINATION_CLASS': 'BookShelf.utilities.pagination.Pagination', 'PAGE_SIZE': 10, + # 'DEFAULT_FILTER_BACKENDS': 'BookShelf.utilities.search.SearchFilter', + 'DEFAULT_FILTER_BACKENDS': [ + 'rest_framework.filters.SearchFilter', + ], } SIMPLE_JWT = { diff --git a/backend/BookShelf/utilities/pagination.py b/backend/BookShelf/utilities/pagination.py index 5f36f98..386a419 100644 --- a/backend/BookShelf/utilities/pagination.py +++ b/backend/BookShelf/utilities/pagination.py @@ -18,3 +18,14 @@ def get_page_size(self, request): self.max_page_size ) return self.page_size + + # For customizing the paginated response + # def get_paginated_response(self, data): + # return Response({ + # 'total_count': self.page.paginator.count, + # 'total_pages': self.page.paginator.num_pages, + # 'current_page': self.page.number, + # 'next': self.get_next_link(), + # 'previous': self.get_previous_link(), + # 'results': data, + # }) diff --git a/backend/BookShelf/utilities/search.py b/backend/BookShelf/utilities/search.py new file mode 100644 index 0000000..945021f --- /dev/null +++ b/backend/BookShelf/utilities/search.py @@ -0,0 +1,33 @@ +from rest_framework.filters import BaseFilterBackend + + +class SearchFilter(BaseFilterBackend): + """ + A custom search filter that allows more flexible query handling. + """ + + def get_search_fields(self, view): + """ + Returns the search fields defined on the view. + """ + return getattr(view, 'search_fields', None) + + def filter_queryset(self, request, queryset, view): + """ + Perform custom filtering based on search fields and query parameters. + """ + search_fields = self.get_search_fields(view) + search_param = request.query_params.get( + 'search') # Default query param is `search` + + if not search_fields or not search_param: + return queryset # No search fields or query parameter, return unfiltered queryset # noqa + + # Build a query dynamically + from django.db.models import Q + query = Q() + for field in search_fields: + # Case-insensitive search + query |= Q(**{f"{field}__icontains": search_param}) + + return queryset.filter(query) diff --git a/backend/publisher_api/migrations/0003_alter_publisher_name.py b/backend/publisher_api/migrations/0003_alter_publisher_name.py new file mode 100644 index 0000000..7c6ca2c --- /dev/null +++ b/backend/publisher_api/migrations/0003_alter_publisher_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.1 on 2024-11-28 20:25 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('publisher_api', '0002_publisher_added_by_publisher_added_date_time_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='publisher', + name='name', + field=models.CharField(db_index=True, max_length=255), + ), + ] diff --git a/backend/publisher_api/models.py b/backend/publisher_api/models.py index 4166a44..49aeb0b 100644 --- a/backend/publisher_api/models.py +++ b/backend/publisher_api/models.py @@ -2,7 +2,7 @@ class Publisher(models.Model): - name = models.CharField(max_length=255) + name = models.CharField(max_length=255, db_index=True) address = models.CharField(max_length=255, blank=True, null=True) website = models.URLField(blank=True, null=True) email = models.EmailField(blank=True, null=True) diff --git a/backend/publisher_api/views/v1.py b/backend/publisher_api/views/v1.py index 64a0f9b..e5d64f5 100644 --- a/backend/publisher_api/views/v1.py +++ b/backend/publisher_api/views/v1.py @@ -1,6 +1,7 @@ from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from rest_framework import status +from rest_framework.filters import SearchFilter from BookShelf.utilities.permissions import IsAdminOrModerator @@ -15,6 +16,9 @@ class PublisherViewSet(ModelViewSet): permission_classes = [ IsAdminOrModerator, ] + filter_backends = [SearchFilter] + search_fields = ['name'] + # search_param = 'q' # Default search query parameter is `search` # authentication_classes = [TokenAuthentication] def perform_create(self, serializer): From dc14a2fd33af82a5212386bc5dfc9621f56ecda1 Mon Sep 17 00:00:00 2001 From: Rezaul Karim Shaon Date: Fri, 29 Nov 2024 02:32:45 +0600 Subject: [PATCH 2/2] done: #171 - search publishers API --- backend/BookShelf/settings.py | 8 ++++---- backend/BookShelf/utilities/{search.py => filters.py} | 0 backend/publisher_api/views/v1.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) rename backend/BookShelf/utilities/{search.py => filters.py} (100%) diff --git a/backend/BookShelf/settings.py b/backend/BookShelf/settings.py index aa85f82..686f8a8 100644 --- a/backend/BookShelf/settings.py +++ b/backend/BookShelf/settings.py @@ -83,10 +83,10 @@ ), 'DEFAULT_PAGINATION_CLASS': 'BookShelf.utilities.pagination.Pagination', 'PAGE_SIZE': 10, - # 'DEFAULT_FILTER_BACKENDS': 'BookShelf.utilities.search.SearchFilter', - 'DEFAULT_FILTER_BACKENDS': [ - 'rest_framework.filters.SearchFilter', - ], + 'DEFAULT_FILTER_BACKENDS': 'BookShelf.utilities.filters.SearchFilter', + # 'DEFAULT_FILTER_BACKENDS': [ + # 'rest_framework.filters.SearchFilter', + # ], } SIMPLE_JWT = { diff --git a/backend/BookShelf/utilities/search.py b/backend/BookShelf/utilities/filters.py similarity index 100% rename from backend/BookShelf/utilities/search.py rename to backend/BookShelf/utilities/filters.py diff --git a/backend/publisher_api/views/v1.py b/backend/publisher_api/views/v1.py index e5d64f5..b3624d4 100644 --- a/backend/publisher_api/views/v1.py +++ b/backend/publisher_api/views/v1.py @@ -1,9 +1,9 @@ from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from rest_framework import status -from rest_framework.filters import SearchFilter from BookShelf.utilities.permissions import IsAdminOrModerator +from BookShelf.utilities.filters import SearchFilter from publisher_api.models import Publisher