Skip to content

Commit 7d7739d

Browse files
committed
enhance api endpoints that provide autocomplete backend for table permission forms #1507:
- Implement similarity search via db extension - endpoints for groups & users
1 parent cdecd89 commit 7d7739d

File tree

1 file changed

+78
-17
lines changed

1 file changed

+78
-17
lines changed

api/views.py

+78-17
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
import sqlalchemy as sqla
1212
import zipstream
1313
from django.contrib.auth.mixins import LoginRequiredMixin
14+
from django.contrib.postgres.search import TrigramSimilarity
1415
from django.core.exceptions import PermissionDenied
1516
from django.db.models import Q
1617
from django.db.utils import IntegrityError
1718
from django.http import Http404, HttpResponse, JsonResponse, StreamingHttpResponse
19+
from django.core.serializers import serialize
20+
1821
from omi.dialects.oep.compiler import JSONCompiler
1922
from omi.structure import OEPMetadata
2023
from rest_framework import status
@@ -715,10 +718,10 @@ def get(self, request, schema, table, row_id=None):
715718
content_type="text/csv",
716719
session=session,
717720
)
718-
response[
719-
"Content-Disposition"
720-
] = 'attachment; filename="{schema}__{table}.csv"'.format(
721-
schema=schema, table=table
721+
response["Content-Disposition"] = (
722+
'attachment; filename="{schema}__{table}.csv"'.format(
723+
schema=schema, table=table
724+
)
722725
)
723726
return response
724727
elif format == "datapackage":
@@ -746,10 +749,10 @@ def get(self, request, schema, table, row_id=None):
746749
content_type="application/zip",
747750
session=session,
748751
)
749-
response[
750-
"Content-Disposition"
751-
] = 'attachment; filename="{schema}__{table}.zip"'.format(
752-
schema=schema, table=table
752+
response["Content-Disposition"] = (
753+
'attachment; filename="{schema}__{table}.zip"'.format(
754+
schema=schema, table=table
755+
)
753756
)
754757
return response
755758
else:
@@ -1133,20 +1136,78 @@ def get(self, request):
11331136
return HttpResponse("All connections closed")
11341137

11351138

1139+
# def get_users(request):
1140+
# string = request.GET["name"]
1141+
# users = login_models.myuser.objects.filter(
1142+
# Q(name__trigram_similar=string) | Q(name__istartswith=string)
1143+
# )
1144+
# return JsonResponse([user.name for user in users], safe=False)
1145+
1146+
11361147
def get_users(request):
1137-
string = request.GET["name"]
1138-
users = login_models.myuser.objects.filter(
1139-
Q(name__trigram_similar=string) | Q(name__istartswith=string)
1140-
)
1141-
return JsonResponse([user.name for user in users], safe=False)
1148+
query = request.GET.get("name", "")
1149+
1150+
# Ensure query is not empty to proceed with filtering
1151+
if query:
1152+
users = (
1153+
login_models.myuser.objects.annotate(
1154+
similarity=TrigramSimilarity("name", query),
1155+
)
1156+
.filter(
1157+
Q(similarity__gt=0.2) | Q(name__istartswith=query),
1158+
)
1159+
.order_by("-similarity")[:6]
1160+
)
1161+
else:
1162+
# Returning an empty list.
1163+
users = login_models.myuser.objects.none()
1164+
1165+
# Convert to list of user names
1166+
user_names = [user.name for user in users]
1167+
1168+
return JsonResponse(user_names, safe=False)
1169+
1170+
1171+
# def get_groups(request):
1172+
# string = request.GET["name"]
1173+
# users = login_models.Group.objects.filter(
1174+
# Q(name__trigram_similar=string) | Q(name__istartswith=string)
1175+
# )
1176+
# return JsonResponse([user.name for user in users], safe=False)
11421177

11431178

11441179
def get_groups(request):
1145-
string = request.GET["name"]
1146-
users = login_models.Group.objects.filter(
1147-
Q(name__trigram_similar=string) | Q(name__istartswith=string)
1180+
"""
1181+
Return all Groups where this user is a member that match
1182+
the current query. The query is input by the User.
1183+
"""
1184+
try:
1185+
user = login_models.myuser.objects.get(id=request.user.id)
1186+
except login_models.myuser.DoesNotExist:
1187+
raise Http404
1188+
1189+
query = request.GET.get("name", None)
1190+
if not query:
1191+
return JsonResponse([], safe=False)
1192+
1193+
user_groups = user.memberships.all().prefetch_related("group")
1194+
groups = [g.group for g in user_groups]
1195+
1196+
# Assuming 'name' is the field you want to search against
1197+
similar_groups = (
1198+
login_models.Group.objects.annotate(
1199+
similarity=TrigramSimilarity("name", query),
1200+
)
1201+
.filter(
1202+
similarity__gt=0.2, # Adjust the threshold as needed
1203+
id__in=[group.id for group in groups],
1204+
)
1205+
.order_by("-similarity")[:5]
11481206
)
1149-
return JsonResponse([user.name for user in users], safe=False)
1207+
1208+
group_names = [group.name for group in similar_groups]
1209+
1210+
return JsonResponse(group_names, safe=False)
11501211

11511212

11521213
def oeo_search(request):

0 commit comments

Comments
 (0)