From 921996984c16b0e3928334a805ded4f0831bbc97 Mon Sep 17 00:00:00 2001
From: "J.-S. Caux" <J.S.Caux@uva.nl>
Date: Sat, 3 Jul 2021 21:10:07 +0200
Subject: [PATCH] Solve search by journal name bug; introduce extra_filters
 concept

---
 scipost_django/api/viewsets/mixins.py            |  7 ++++++-
 .../journals/api/filtersets/publication.py       |  1 -
 .../journals/api/viewsets/publication.py         | 16 +++++++++++++---
 3 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/scipost_django/api/viewsets/mixins.py b/scipost_django/api/viewsets/mixins.py
index 651381023..fdb3c5cdd 100644
--- a/scipost_django/api/viewsets/mixins.py
+++ b/scipost_django/api/viewsets/mixins.py
@@ -17,6 +17,11 @@ class FilteringOptionsActionMixin:
         """
         Translate the filterset base filters into list of filtering options.
         """
+        advanced_fields_dict = { **self.filterset_class.get_fields() }
+        if hasattr(self, 'extra_filters'):
+            for (label, queryspec) in self.extra_filters.items():
+                advanced_fields_dict[label] = queryspec['lookups']
+
         filtering_options = {
             'ordering': self.ordering_fields,
             'basic': [
@@ -27,7 +32,7 @@ class FilteringOptionsActionMixin:
                     'label': key.replace('__', '/').replace('_', ' ').title(),
                     'field': key,
                     'lookups': val
-                } for (key, val) in self.filterset_class.get_fields().items()
+                } for (key, val) in advanced_fields_dict.items()
             ]
         }
         return Response(filtering_options)
diff --git a/scipost_django/journals/api/filtersets/publication.py b/scipost_django/journals/api/filtersets/publication.py
index 7033a2cbf..83a30d765 100644
--- a/scipost_django/journals/api/filtersets/publication.py
+++ b/scipost_django/journals/api/filtersets/publication.py
@@ -11,7 +11,6 @@ class PublicationPublicAPIFilterSet(df_filters.FilterSet):
     class Meta:
         model = Publication
         fields = {
-            'in_journal__name': ['icontains', 'istartswith', 'exact'],
             'title': ['icontains', 'contains', 'istartswith', 'iregex', 'regex'],
             'author_list': ['icontains', 'contains', 'iregex', 'regex'],
             'abstract': ['icontains', 'contains', 'iregex', 'regex'],
diff --git a/scipost_django/journals/api/viewsets/publication.py b/scipost_django/journals/api/viewsets/publication.py
index 2e5e798ee..0c8ed2bee 100644
--- a/scipost_django/journals/api/viewsets/publication.py
+++ b/scipost_django/journals/api/viewsets/publication.py
@@ -2,11 +2,11 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
-from django_filters import rest_framework as df_filters
+from django.db.models import Q
 
-from rest_framework import viewsets
 from rest_framework.permissions import AllowAny
 
+from api.viewsets.base import ExtraFilteredReadOnlyModelViewSet
 from api.viewsets.mixins import FilteringOptionsActionMixin
 
 from journals.models import Publication
@@ -17,7 +17,7 @@ from journals.api.serializers import PublicationPublicSerializer
 
 class PublicationPublicAPIViewSet(
         FilteringOptionsActionMixin,
-        viewsets.ReadOnlyModelViewSet):
+        ExtraFilteredReadOnlyModelViewSet):
     queryset = Publication.objects.published()
     permission_classes = [AllowAny,]
     serializer_class = PublicationPublicSerializer
@@ -26,6 +26,16 @@ class PublicationPublicAPIViewSet(
     search_fields = ['title', 'author_list', 'abstract', 'doi_label']
     ordering_fields = ['publication_date',]
     filterset_class = PublicationPublicAPIFilterSet
+    extra_filters = {
+        'journal__name': {
+            'fields': [
+                'in_journal__name',
+                'in_issue__in_journal__name',
+                'in_issue__in_volume__in_journal__name'
+            ],
+            'lookups': ['icontains', 'istartswith', 'iexact', 'exact'],
+        }
+    }
     default_filtering_fields = [
         'title__icontains',
         'author_list__icontains',
-- 
GitLab