Skip to content

Commit

Permalink
fixup! ✨(backend) allow to filter member on team access endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mjeammet committed May 3, 2024
1 parent f1162e3 commit 0a92b13
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 48 deletions.
30 changes: 30 additions & 0 deletions src/backend/core/api/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Filters for viewsets."""

from django.contrib.postgres.search import TrigramSimilarity
from django.db.models import Func, Max, Value
from django.db.models.functions import Coalesce

SIMILARITY_THRESHOLD = 0.04


def get_user_queryset(queryset, search_field, query):
"""
Filters user queryset by case-insensitive and accent-insensitive trigram similarity
"""

similarity = Max(
TrigramSimilarity(
Coalesce(Func(f"{search_field}__email", function="unaccent"), Value("")),
Func(Value(query), function="unaccent"),
)
+ TrigramSimilarity(
Coalesce(Func(f"{search_field}__name", function="unaccent"), Value("")),
Func(Value(query), function="unaccent"),
)
)
queryset = (
queryset.annotate(similarity=similarity)
.filter(similarity__gte=SIMILARITY_THRESHOLD)
.order_by("-similarity")
)
return queryset
59 changes: 11 additions & 48 deletions src/backend/core/api/viewsets.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,21 @@
"""API endpoints"""

from django.contrib.postgres.search import TrigramSimilarity
from django.db.models import Func, Max, OuterRef, Prefetch, Q, Subquery, Value
from django.db.models.functions import Coalesce
from django.db.models import Func, OuterRef, Prefetch, Q, Subquery, Value

from rest_framework import (
decorators,
exceptions,
filters,
mixins,
pagination,
response,
throttling,
viewsets,
)
from rest_framework import filters as drf_filters

from core import models

from . import permissions, serializers

SIMILARITY_THRESHOLD = 0.04
from core.api import filters, permissions, serializers


class NestedGenericViewSet(viewsets.GenericViewSet):
Expand Down Expand Up @@ -212,25 +208,7 @@ def get_queryset(self):

# Search by case-insensitive and accent-insensitive trigram similarity
if query := self.request.GET.get("q", ""):
similarity = Max(
TrigramSimilarity(
Coalesce(
Func("identities__email", function="unaccent"), Value("")
),
Func(Value(query), function="unaccent"),
)
+ TrigramSimilarity(
Coalesce(
Func("identities__name", function="unaccent"), Value("")
),
Func(Value(query), function="unaccent"),
)
)
queryset = (
queryset.annotate(similarity=similarity)
.filter(similarity__gte=SIMILARITY_THRESHOLD)
.order_by("-similarity")
)
queryset = filters.get_user_queryset(queryset, "identities", query)

return queryset

Expand Down Expand Up @@ -262,7 +240,7 @@ class TeamViewSet(

permission_classes = [permissions.AccessPermission]
serializer_class = serializers.TeamSerializer
filter_backends = [filters.OrderingFilter]
filter_backends = [drf_filters.OrderingFilter]
ordering_fields = ["created_at"]
ordering = ["-created_at"]
queryset = models.Team.objects.all()
Expand Down Expand Up @@ -327,7 +305,7 @@ class TeamAccessViewSet(
list_serializer_class = serializers.TeamAccessReadOnlySerializer
detail_serializer_class = serializers.TeamAccessSerializer

filter_backends = [filters.OrderingFilter]
filter_backends = [drf_filters.OrderingFilter]
ordering = ["role"]
ordering_fields = ["role", "email", "name"]

Expand Down Expand Up @@ -355,28 +333,13 @@ def get_queryset(self):
"""Return the queryset according to the action."""
queryset = super().get_queryset()
queryset = queryset.filter(team=self.kwargs["team_id"])
if query := self.request.GET.get("q", ""):
similarity = Max(
TrigramSimilarity(
Coalesce(
Func("user__identities__email", function="unaccent"), Value("")
),
Func(Value(query), function="unaccent"),
)
+ TrigramSimilarity(
Coalesce(
Func("user__identities__name", function="unaccent"), Value("")
),
Func(Value(query), function="unaccent"),
)
)
queryset = (
queryset.annotate(similarity=similarity)
.filter(similarity__gte=SIMILARITY_THRESHOLD)
.order_by("-similarity")
)

if self.action in {"list", "retrieve"}:
if query := self.request.GET.get("q", ""):
queryset = filters.get_user_queryset(
queryset, "user__identities", query
)

# Determine which role the logged-in user has in the team
user_role_query = models.TeamAccess.objects.filter(
user=self.request.user, team=self.kwargs["team_id"]
Expand Down

0 comments on commit 0a92b13

Please sign in to comment.