diff --git a/django_api/views.py b/django_api/views.py index 49126c72..79c0ec21 100644 --- a/django_api/views.py +++ b/django_api/views.py @@ -1,303 +1,303 @@ from django.contrib.auth.models import AbstractUser from django.shortcuts import render from django.contrib.auth import authenticate, login, logout from django.shortcuts import render from django.http import HttpResponse, HttpResponseRedirect, Http404, JsonResponse from .models import * from .serializers import * from rest_framework import viewsets, filters, generics from django.utils.decorators import method_decorator from django.views.decorators.cache import cache_page from rest_framework.authentication import BasicAuthentication from rest_framework.permissions import IsAuthenticatedOrReadOnly from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework_tracking.mixins import LoggingMixin from itertools import chain from django.db.models import Count, Max from dj_rql.filter_cls import RQLFilterClass from urllib.parse import unquote from datetime import date import ipaddress class JournalViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] search_fields = ['name'] filter_backends = (filters.SearchFilter,) queryset = Journal.objects.all() serializer_class = JournalSerializer class JournalLightViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] search_fields = ['name'] filter_backends = (filters.SearchFilter,) queryset = Journal.objects.all().prefetch_related('publisher', 'language', 'oa_status') serializer_class = JournalLightSerializer @method_decorator(cache_page(4 * 60 * 60)) def dispatch(self, request, *args, **kwargs): # print('dispatch() called') return super().dispatch(request, *args, **kwargs) @method_decorator(cache_page(4 * 60 * 60)) def list(self, request): # print('list() called') serializer = self.serializer_class(self.queryset, many=True) return Response(serializer.data) class OrgaViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = OrgaSerializer queryset = Organization.objects.filter( is_funder=False ) class ConditionSetFilters(RQLFilterClass): """ API filters for the essential query on ConditionSets Arguments can include a journal id, zero to two organization ids, validity dates and a condition type. Request examples: http://127.0.0.1:8000/api/conditionset/?and(eq(journalcondition.journal.id,3),eq(organizationcondition.organization.id,11),eq(condition_type.id,1)) http://127.0.0.1:8000/api/conditionset/?and(eq(journalcondition.journal.id,14),ne(condition_type.id,2),ge(journalcondition.valid_until,2021-08-20),le(journalcondition.valid_from,2021-08-20),ge(organizationcondition.valid_until,2021-08-20),le(organizationcondition.valid_from,2021-08-20)) """ MODEL = ConditionSet DISTINCT = True FILTERS = ( 'id', { 'namespace': 'journalcondition', 'filters': ['id', 'valid_from', 'valid_until', { 'namespace': 'journal', 'filters': ['id', ], } ], }, { 'namespace': 'organizationcondition', 'filters': ['id', 'valid_from', 'valid_until', { 'namespace': 'organization', 'filters': ['id', ] } ], }, { 'namespace': 'condition_type', 'filters': ['id', ], }, ) class MyLoggingMixin(LoggingMixin): """ Supercharge drf_tracking.LoggingMixin to get the real IP address in the OpenShift infrastructure """ def _get_ip_address(self, request): """Get the remote ip address the request was generated from.""" ipaddr = request.META.get("HTTP_X_FORWARDED_FOR", None) if ipaddr: ipaddr = ipaddr.split(",")[0] else: - ipaddr = request.META.get("X-Real-IP", None) + ipaddr = request.META.get("HTTP_X_REAL_IP", None) if ipaddr: ipaddr = ipaddr.split(",")[0] else: ipaddr = request.META.get("REMOTE_ADDR", "").split(",")[0] # Account for IPv4 and IPv6 addresses, each possibly with port appended. Possibilities are: # # # :port # []:port # Note that ipv6 addresses are colon separated hex numbers possibles = (ipaddr.lstrip("[").split("]")[0], ipaddr.split(":")[0]) for addr in possibles: try: return str(ipaddress.ip_address(addr)) except ValueError: pass return ipaddr class ConditionSetViewSet(MyLoggingMixin, viewsets.ModelViewSet): """ ViewSet for ConditionSets The QuerySet obtained from the database is annotated to obtain the desired sorting order, i.e. by condition_type, then subtype, then a calculated score so that institutions receive more attention than funders within a given type/subtype """ authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] queryset = ConditionSet.objects.all().annotate(include_funder=Max('organization__is_funder')).order_by('condition_type','subtype', 'include_funder','comment') # queryset = ConditionSet.objects.values('term__version__description') serializer_class = ConditionSetSerializer # serializer_class = ConditionGroupedSerializer rql_filter_class = ConditionSetFilters #.objects.values('term__version.description') class ConditionSetLightViewSet(MyLoggingMixin, viewsets.ModelViewSet): """ Light-weight ViewSet for ConditionSets The QuerySet obtained from the database is annotated to obtain the desired sorting order, i.e. by condition_type, then subtype, then a calculated score so that institutions receive more attention than funders within a given type/subtype """ authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] queryset = ConditionSet.objects.all().annotate(include_funder=Max('organization__is_funder')).order_by('condition_type','subtype','include_funder','comment') serializer_class = ConditionSetLightSerializer rql_filter_class = ConditionSetFilters class FunderViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = OrgaSerializer queryset = Organization.objects.filter( is_funder=True ) class TermViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = TermSerializer queryset = Term.objects.all() class CountryViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = CountrySerializer queryset = Country.objects.all() class LanguageViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = LanguageSerializer queryset = Language.objects.all() class IssnViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = IssnSerializer queryset = Issn.objects.all() class OaViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = OaSerializer queryset = Oa.objects.all() class PublisherViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = PublisherSerializer queryset = Publisher.objects.all() class VersionViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = VersionSerializer queryset = Version.objects.all() class LicenceViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = LicenceSerializer queryset = Licence.objects.all() class Cost_factor_typeViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = Cost_factor_typeSerializer queryset = Cost_factor_type.objects.all() class Cost_factorViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = Cost_factorSerializer queryset = Cost_factor.objects.all() class ConditionTypeViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = ConditionTypeSerializer queryset = ConditionType.objects.all() class OrganizationConditionViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = OrganizationConditionSerializer queryset = OrganizationCondition.objects.all() class JournalConditionViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = JournalConditionSerializer queryset = JournalCondition.objects.all() class OrganizationConditionViewSet(viewsets.ModelViewSet): authentification_classes = (BasicAuthentication,) permission_classes = [IsAuthenticatedOrReadOnly] serializer_class = OrganizationConditionSerializer queryset = OrganizationCondition.objects.all() # Count number of different version # OrganizationCondition.objects.annotate(version_count=Count('condition_set__term__version')) # OrganizationCondition.objects # .values('condition_set__term__version') #what to group by # .annotate(version_count=Count('condition_set__term__version')) # what to aggregate # group by version and count # OrganizationCondition.objects.values('condition_set__term__version').annotate(version_count=Count('condition_set__term__version')) # source https://hakibenita.com/django-group-by-sql # https://docs.djangoproject.com/en/3.2/topics/db/aggregation/ # OrganizationCondition.objects.values('condition_set__term__version').filter(organization_id=1).annotate(version_count=Count('condition_set__term__version')) \ No newline at end of file