55from django .core .paginator import Paginator
66from django .contrib .auth .models import Group , User
77from django .conf import settings
8- from django .db .models import Q
8+ from django .db .models import Q , Count
99from django .http import HttpResponse , Http404
1010from django .utils .translation import gettext_lazy as _
1111from django_filters import rest_framework as filters
@@ -176,6 +176,8 @@ def get_permissions(self):
176176 base_permissions = super (self .__class__ , self ).get_permissions ()
177177 if self .action in ["csv_export" , "xlsx_export" ]:
178178 base_permissions = (TableCustomActionPermissions (),)
179+ elif self .action in ["search" ]:
180+ base_permissions = ()
179181 return base_permissions
180182
181183 def create (self , request ):
@@ -280,6 +282,27 @@ def create_contacts_table(self, request):
280282 }
281283 return Response (response_data )
282284
285+ @action (
286+ detail = False ,
287+ methods = ["get" ],
288+ name = _ ("Find tables containing text" ),
289+ url_path = "search" ,
290+ )
291+ def search (self , request ):
292+ needle = request .GET .get ("query" ).strip ()
293+ tables = models .Table .objects .all ()
294+ table_ids = []
295+ for table in tables :
296+ # TODO: check table view permissions
297+ table_ids .append (table .id )
298+
299+ queryset = models .Entry .objects .filter (
300+ table__id__in = table_ids , data__icontains = needle
301+ ).all ().values ("table" ).annotate (total = Count ("table" )).order_by ("table" )
302+
303+ serializer = serializers .tables .TableSearchCountSerializer (queryset , many = True )
304+ return Response (serializer .data )
305+
283306 @action (
284307 detail = True ,
285308 methods = ["post" ],
@@ -1046,78 +1069,6 @@ def csv_export(self, request, pk):
10461069 return response
10471070
10481071
1049- class EntryGlobalViewSet (viewsets .ModelViewSet ):
1050- queryset = models .Entry .objects .all ().order_by ("id" )
1051- pagination_class = EntriesPagination
1052- serializer_class = serializers .entries .EntryReadSerializer
1053- # filter_backends = (drf_filters.SearchFilter, )
1054- # search_fields = ("data", )
1055- # # permission_classes = (TableEntryPermissions, )
1056-
1057- # def list(self, request):
1058- # page = self.paginate_queryset(self.queryset)
1059-
1060- # if page is not None:
1061- # serializer = serializers.entries.EntryReadSerializer(
1062- # page,
1063- # many=True,
1064- # context={"request": request},
1065- # )
1066- # return self.get_paginated_response(serializer.data)
1067- # serializer = serializers.entries.EntryReadSerializer(self.queryset, many=True)
1068- # return Response(serializer.data)
1069-
1070- def list (self , request ):
1071- return Http404
1072-
1073- def create (self , request ):
1074- return Http404
1075-
1076- def retrieve (self , request , pk = None ):
1077- return Http404
1078-
1079- def update (self , request , pk = None ):
1080- return Http404
1081-
1082- def partial_update (self , request , pk = None ):
1083- return Http404
1084-
1085- def destroy (self , request , pk = None ):
1086- return Http404
1087-
1088- @action (
1089- detail = False ,
1090- methods = ["get" ],
1091- url_name = "search" ,
1092- url_path = "search" ,
1093- )
1094- def search (self , request ):
1095- """ Text search over the entries """
1096-
1097- needle = request .GET .get ("query" )
1098-
1099- tables = models .Table .objects .all ()
1100- table_ids = []
1101- for table in tables :
1102- # TODO: apply permissions
1103- table_ids .append (table .id )
1104-
1105- queryset = models .Entry .objects .filter (
1106- table__id__in = table_ids , data__icontains = needle ).order_by ("id" )
1107- page = self .paginate_queryset (queryset )
1108-
1109- if page is not None :
1110- serializer = serializers .entries .EntryReadSerializer (
1111- page ,
1112- many = True ,
1113- context = {"request" : request },
1114- )
1115- return self .get_paginated_response (serializer .data )
1116-
1117- serializer = serializers .entries .EntryReadSerializer (queryset , many = True )
1118- return Response (serializer .data )
1119-
1120-
11211072class EntryViewSet (viewsets .ModelViewSet ):
11221073 pagination_class = EntriesPagination
11231074 serializer_class = serializers .entries .EntrySerializer
@@ -1133,6 +1084,7 @@ def list(self, request, table_pk):
11331084
11341085 str_fields = request .GET .get ("__fields" , "" ) if request else None
11351086 str_order = request .GET .get ("__order" , "" ) if request else None
1087+ str_search = request .GET .get ("search" , "" ).strip () if request else None
11361088 table_fields = {x .name : x .field_type for x in table .fields .all ().order_by ("id" )}
11371089 default_fields = {x .name : x for x in table .default_fields .all ().order_by ("id" )}
11381090
@@ -1158,6 +1110,10 @@ def list(self, request, table_pk):
11581110 queryset = table .entries .filter (filter_dict ).order_by ("id" )
11591111 # queryset = table.entries.annotate(date_field=Cast(KeyTextTransform('data_iesire', "data"), DateField())).filter(date_field__exact='2020-07-21').order_by("id")
11601112
1113+ # simple text search over the entire data field
1114+ if str_search :
1115+ queryset = queryset .filter (data__icontains = str_search )
1116+
11611117 page = self .paginate_queryset (queryset )
11621118
11631119 if page is not None :
0 commit comments