From 6fc6efad0ee57e430903b0d24c6e925652ff3714 Mon Sep 17 00:00:00 2001 From: Étienne Loks Date: Thu, 14 Oct 2021 18:56:53 +0200 Subject: Syndication - search limitation; API to send available types --- ishtar_common/rest.py | 89 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 83 insertions(+), 6 deletions(-) (limited to 'ishtar_common/rest.py') diff --git a/ishtar_common/rest.py b/ishtar_common/rest.py index 8b4419e82..602bba293 100644 --- a/ishtar_common/rest.py +++ b/ishtar_common/rest.py @@ -1,8 +1,12 @@ +from django.conf import settings +from django.db.models import Q +from django.utils.translation import activate, deactivate + from rest_framework import authentication, permissions from rest_framework.response import Response from rest_framework.views import APIView -from ishtar_common.models import ApiSearchModel +from ishtar_common import models_rest from ishtar_common.views_item import get_item @@ -10,7 +14,7 @@ class IpModelPermission(permissions.BasePermission): def has_permission(self, request, view): if not request.user or not getattr(request.user, "apiuser", None): return False - ip_addr = request.META['REMOTE_ADDR'] + ip_addr = request.META["REMOTE_ADDR"] q = view.search_model_query(request).filter(user__ip=ip_addr) return bool(q.count()) @@ -25,14 +29,17 @@ class SearchAPIView(APIView): super(SearchAPIView, self).__init__(**kwargs) def search_model_query(self, request): - return ApiSearchModel.objects.filter( + return models_rest.ApiSearchModel.objects.filter( user=request.user.apiuser, content_type__app_label=self.model._meta.app_label, - content_type__model=self.model._meta.model_name) + content_type__model=self.model._meta.model_name, + ) def get(self, request, format=None): _get_item = get_item( - self.model, "get_" + self.model.SLUG, self.model.SLUG, + self.model, + "get_" + self.model.SLUG, + self.model.SLUG, # TODO: own_table_cols=get_table_cols_for_ope() - adapt columns ) search_model = self.search_model_query(request).all()[0] @@ -45,4 +52,74 @@ class SearchAPIView(APIView): request.GET._mutable = False response = _get_item(request) return response - #return Response({}) + # return Response({}) + + +class FacetAPIView(APIView): + authentication_classes = (authentication.TokenAuthentication,) + permission_classes = (permissions.IsAuthenticated, IpModelPermission) + # keep order for models and select_forms: first model match first select form, ... + models = [] + select_forms = [] + + def __init__(self, **kwargs): + assert self.models + assert self.select_forms + assert len(self.models) == len(self.select_forms) + super().__init__(**kwargs) + + def get(self, request, format=None): + values = {} + base_queries = self._get_base_search_model_queries() + for idx, select_form in enumerate(self.select_forms): + # only send types matching permissions + model, q = base_queries[idx] + if ( + not models_rest.ApiSearchModel.objects.filter(user=request.user.apiuser) + .filter(q) + .count() + ): + continue + ct_model = f"{model._meta.app_label}.{model._meta.model_name}" + values[ct_model] = [] + for type in select_form.TYPES: + values_ct = [] + for item in type.model.objects.filter(available=True).all(): + key = item.slug if hasattr(item, "slug") else item.txt_idx + values_ct.append((key, str(item))) + search_key = model.ALT_NAMES[type.key].search_key + search_keys = [] + for language_code, language_lbl in settings.LANGUAGES: + activate(language_code) + search_keys.append(str(search_key).lower()) + deactivate() + values[ct_model].append( + [search_keys, values_ct] + ) + return Response(values) + + def _get_base_search_model_queries(self): + """ + Get list of (model, query) to match content_types + """ + return [ + ( + model, + Q( + content_type__app_label=model._meta.app_label, + content_type__model=model._meta.model_name, + ), + ) + for model in self.models + ] + + def search_model_query(self, request): + q = None + for __, base_query in self._get_base_search_model_queries(): + if not q: + q = base_query + else: + q |= base_query + return models_rest.ApiSearchModel.objects.filter( + user=request.user.apiuser + ).filter(q) -- cgit v1.2.3