Skip to content

Commit

Permalink
OpenConceptLab/ocl_issues#1277 | Using cached lookup API for all lookups
Browse files Browse the repository at this point in the history
  • Loading branch information
snyaggarwal committed Apr 26, 2022
1 parent b60ca10 commit c538263
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 23 deletions.
25 changes: 24 additions & 1 deletion core/concepts/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from core.common.constants import INCLUDE_INVERSE_MAPPINGS_PARAM, INCLUDE_MAPPINGS_PARAM, INCLUDE_EXTRAS_PARAM, \
INCLUDE_PARENT_CONCEPTS, INCLUDE_CHILD_CONCEPTS, INCLUDE_SOURCE_VERSIONS, INCLUDE_COLLECTION_VERSIONS, \
CREATE_PARENT_VERSION_QUERY_PARAM, INCLUDE_HIERARCHY_PATH, INCLUDE_PARENT_CONCEPT_URLS, \
INCLUDE_CHILD_CONCEPT_URLS, HEAD, INCLUDE_SUMMARY, INCLUDE_VERBOSE_REFERENCES
INCLUDE_CHILD_CONCEPT_URLS, HEAD, INCLUDE_SUMMARY, INCLUDE_VERBOSE_REFERENCES, VERBOSE_PARAM
from core.common.fields import EncodedDecodedCharField
from core.common.utils import to_parent_uri_from_kwargs
from core.concepts.models import Concept, LocalizedText
Expand Down Expand Up @@ -217,6 +217,29 @@ def get_summary(self, obj):
return None


class ConceptLookupListSerializer(ModelSerializer):
uuid = CharField(source='id')
id = EncodedDecodedCharField(source='mnemonic')
url = CharField(read_only=True, source='uri')

class Meta:
model = Concept
fields = ('uuid', 'id', 'display_name', 'url')

def __init__(self, *args, **kwargs): # pylint: disable=too-many-branches
request = get(kwargs, 'context.request')
params = get(request, 'query_params')
self.query_params = params.dict() if params else {}
self.is_verbose = self.query_params.get(VERBOSE_PARAM) in ['true', True]
try:
if not self.is_verbose:
self.fields.pop('display_name', None)
except: # pylint: disable=bare-except
pass

super().__init__(*args, **kwargs)


class ConceptListSerializer(ConceptAbstractSerializer):
type = CharField(source='resource_type', read_only=True)
id = EncodedDecodedCharField(source='mnemonic')
Expand Down
8 changes: 8 additions & 0 deletions core/concepts/urls.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
from django.urls import path
from django.views.decorators.cache import cache_page

from core.concepts.feeds import ConceptFeed
from . import views

urlpatterns = [
path('', views.ConceptListView.as_view(), name='concept-list'),
path(
'lookup/',
cache_page(
timeout=60 * 60 * 24, key_prefix='cache_lookup'
)(views.ConceptLookupValuesView.as_view()),
name='concept-lookup-list'
),
path(
"<str:concept>/",
views.ConceptRetrieveUpdateDestroyView.as_view(),
Expand Down
74 changes: 52 additions & 22 deletions core/concepts/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
from pydash import get
from rest_framework import status
from rest_framework.generics import RetrieveAPIView, DestroyAPIView, ListCreateAPIView, RetrieveUpdateDestroyAPIView, \
UpdateAPIView
UpdateAPIView, ListAPIView
from rest_framework.mixins import CreateModelMixin
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser
from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser, AllowAny
from rest_framework.response import Response
from rest_framework.views import APIView

Expand All @@ -25,7 +25,7 @@
from core.common.tasks import delete_concept, make_hierarchy
from core.common.utils import to_parent_uri_from_kwargs
from core.common.views import SourceChildCommonBaseView, SourceChildExtrasView, \
SourceChildExtraRetrieveUpdateDestroyView
SourceChildExtraRetrieveUpdateDestroyView, BaseAPIView
from core.concepts.constants import PARENT_VERSION_NOT_LATEST_CANNOT_UPDATE_CONCEPT
from core.concepts.documents import ConceptDocument
from core.concepts.models import Concept, LocalizedText
Expand All @@ -35,7 +35,7 @@
ConceptDetailSerializer, ConceptListSerializer, ConceptDescriptionSerializer, ConceptNameSerializer,
ConceptVersionDetailSerializer,
ConceptVersionListSerializer, ConceptSummarySerializer, ConceptMinimalSerializer,
ConceptChildrenSerializer, ConceptParentsSerializer)
ConceptChildrenSerializer, ConceptParentsSerializer, ConceptLookupListSerializer)
from core.mappings.serializers import MappingListSerializer


Expand All @@ -54,6 +54,54 @@ def get_detail_serializer(self, obj, data=None, files=None, partial=False):
def get_queryset(self):
return Concept.get_base_queryset(self.params)

def set_parent_resource(self, __pop=True):
parent_resource = None
source = self.kwargs.pop('source', None) if __pop else self.kwargs.get('source', None)
collection = self.kwargs.pop('collection', None) if __pop else self.kwargs.get('collection', None)
container_version = self.kwargs.pop('version', HEAD) if __pop else self.kwargs.get('version', HEAD)
if 'org' in self.kwargs:
filters = dict(organization__mnemonic=self.kwargs['org'])
else:
username = self.request.user.username if self.user_is_self else self.kwargs.get('user')
filters = dict(user__username=username)
if source:
from core.sources.models import Source
parent_resource = Source.get_version(source, container_version or HEAD, filters)
if collection:
from core.collections.models import Collection
parent_resource = Collection.get_version(source, container_version or HEAD, filters)
self.kwargs['parent_resource'] = self.parent_resource = parent_resource


# this is a cached view (expiry 24 hours)
# used for TermBrowser forms lookup values -- map-types/locales/datatypes/etc
class ConceptLookupValuesView(ListAPIView, BaseAPIView): # pragma: no cover
serializer_class = ConceptLookupListSerializer
permission_classes = (AllowAny, )

def set_parent_resource(self):
parent_resource = None
source = self.kwargs.get('source', None)
if 'org' in self.kwargs:
filters = dict(organization__mnemonic=self.kwargs['org'])
else:
username = self.request.user.username if self.user_is_self else self.kwargs.get('user')
filters = dict(user__username=username)
if source:
from core.sources.models import Source
parent_resource = Source.get_version(source, HEAD, filters)
self.kwargs['parent_resource'] = self.parent_resource = parent_resource

def get_queryset(self):
self.set_parent_resource()
if self.parent_resource:
queryset = self.parent_resource.concepts_set.filter(id=F('versioned_object_id'))
if self.is_verbose():
queryset = queryset.prefetch_related('names')
return queryset

raise Http404()


class ConceptListView(ConceptBaseView, ListWithHeadersMixin, CreateModelMixin):
serializer_class = ConceptListSerializer
Expand Down Expand Up @@ -116,24 +164,6 @@ def get(self, request, *args, **kwargs):
self.check_object_permissions(request, self.parent_resource)
return self.list(request, *args, **kwargs)

def set_parent_resource(self, __pop=True):
parent_resource = None
source = self.kwargs.pop('source', None) if __pop else self.kwargs.get('source', None)
collection = self.kwargs.pop('collection', None) if __pop else self.kwargs.get('collection', None)
container_version = self.kwargs.pop('version', HEAD) if __pop else self.kwargs.get('version', HEAD)
if 'org' in self.kwargs:
filters = dict(organization__mnemonic=self.kwargs['org'])
else:
username = self.request.user.username if self.user_is_self else self.kwargs.get('user')
filters = dict(user__username=username)
if source:
from core.sources.models import Source
parent_resource = Source.get_version(source, container_version or HEAD, filters)
if collection:
from core.collections.models import Collection
parent_resource = Collection.get_version(source, container_version or HEAD, filters)
self.kwargs['parent_resource'] = self.parent_resource = parent_resource

def post(self, request, **_):
self.set_parent_resource()
if not self.parent_resource:
Expand Down

0 comments on commit c538263

Please sign in to comment.