From dc87a5d77bfd8a8f57c2d277f206c96c96e0a5c5 Mon Sep 17 00:00:00 2001
From: Yohann D'ANELLO <yohann.danello@gmail.com>
Date: Sat, 8 Feb 2020 17:17:00 +0100
Subject: [PATCH] Filter notes and aliases by aliases (regexp) or note type

---
 apps/api/note/views.py | 62 ++++++++++++++++++++++++++++++++++++++++--
 apps/api/urls.py       | 13 ++++-----
 2 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/apps/api/note/views.py b/apps/api/note/views.py
index c6aa7689..5c7cdc96 100644
--- a/apps/api/note/views.py
+++ b/apps/api/note/views.py
@@ -2,6 +2,7 @@
 # Copyright (C) 2018-2020 by BDE ENS Paris-Saclay
 # SPDX-License-Identifier: GPL-3.0-or-later
 
+from django.db.models import Q
 from note.models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
 from note.models.transactions import TransactionTemplate, Transaction, MembershipTransaction
 from .serializers import NoteSerializer, NotePolymorphicSerializer, NoteClubSerializer, NoteSpecialSerializer, NoteUserSerializer, AliasSerializer, \
@@ -52,12 +53,40 @@ class NoteUserViewSet(viewsets.ModelViewSet):
 class NotePolymorphicViewSet(viewsets.ModelViewSet):
     """
     REST API View set.
-    The djangorestframework plugin will get all `NoteUser` objects, serialize it to JSON with the given serializer,
-    then render it on /api/note/user/
+    The djangorestframework plugin will get all `Note` objects (with polymorhism), serialize it to JSON with the given serializer,
+    then render it on /api/note/note/
     """
     queryset = Note.objects.all()
     serializer_class = NotePolymorphicSerializer
 
+    def get_queryset(self):
+        """
+        Parse query and apply filters.
+        :return: The filtered set of requested notes
+        """
+        queryset = Note.objects.all()
+
+        alias = self.request.query_params.get("alias", ".*")
+        queryset = queryset.filter(Q(alias__name__regex=alias) | Q(alias__normalized_name__regex=alias))
+
+        note_id = self.request.query_params.get("id", None)
+        if note_id:
+            queryset = queryset.filter(id=note_id)
+
+        note_type = self.request.query_params.get("type", None)
+        if note_type:
+            l = str(note_type).lower()
+            if "user" in l:
+                queryset = queryset.filter(polymorphic_ctype__model="noteuser")
+            elif "club" in l:
+                queryset = queryset.filter(polymorphic_ctype__model="noteclub")
+            elif "special" in l:
+                queryset = queryset.filter(polymorphic_ctype__model="notespecial")
+            else:
+                queryset = queryset.none()
+
+        return queryset
+
 
 class AliasViewSet(viewsets.ModelViewSet):
     """
@@ -68,6 +97,35 @@ class AliasViewSet(viewsets.ModelViewSet):
     queryset = Alias.objects.all()
     serializer_class = AliasSerializer
 
+    def get_queryset(self):
+        """
+        Parse query and apply filters.
+        :return: The filtered set of requested aliases
+        """
+
+        queryset = Alias.objects.all()
+
+        alias = self.request.query_params.get("alias", ".*")
+        queryset = queryset.filter(Q(name__regex=alias) | Q(normalized_name__regex=alias))
+
+        note_id = self.request.query_params.get("note", None)
+        if note_id:
+            queryset = queryset.filter(id=note_id)
+
+        note_type = self.request.query_params.get("type", None)
+        if note_type:
+            l = str(note_type).lower()
+            if "user" in l:
+                queryset = queryset.filter(note__polymorphic_ctype__model="noteuser")
+            elif "club" in l:
+                queryset = queryset.filter(note__polymorphic_ctype__model="noteclub")
+            elif "special" in l:
+                queryset = queryset.filter(note__polymorphic_ctype__model="notespecial")
+            else:
+                queryset = queryset.none()
+
+        return queryset
+
 
 class TransactionTemplateViewSet(viewsets.ModelViewSet):
     """
diff --git a/apps/api/urls.py b/apps/api/urls.py
index 3c5f6c78..60758050 100644
--- a/apps/api/urls.py
+++ b/apps/api/urls.py
@@ -6,7 +6,6 @@ from django.conf.urls import url, include
 from django.contrib.auth.models import User
 from rest_framework import routers, serializers, viewsets
 
-from note.models import Alias
 from .activity.urls import register_activity_urls
 from .members.urls import register_members_urls
 from .note.urls import register_note_urls
@@ -18,7 +17,7 @@ class UserSerializer(serializers.ModelSerializer):
     """
     class Meta:
         model = User
-        fields = '__all__'
+        exclude = ('password', 'groups', 'user_permissions',)
 
 class UserViewSet(viewsets.ModelViewSet):
     """
@@ -34,17 +33,17 @@ router = routers.DefaultRouter()
 router.register('user', UserViewSet)
 
 # Routers for members app
-register_members_urls(router, r'members')
+register_members_urls(router, 'members')
 
 # Routers for activity app
-register_activity_urls(router, r'activity')
+register_activity_urls(router, 'activity')
 
 # Routers for note app
-register_note_urls(router, r'note')
+register_note_urls(router, 'note')
 
 # Wire up our API using automatic URL routing.
 # Additionally, we include login URLs for the browsable API.
 urlpatterns = [
-    url(r'^', include(router.urls)),
-    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
+    url('^', include(router.urls)),
+    url('^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
 ]
\ No newline at end of file
-- 
GitLab