pulseapi/creators/views.py (53 lines of code) (raw):

from itertools import chain from django.db.models import Q from django.conf import settings from django_filters.rest_framework import DjangoFilterBackend from rest_framework import exceptions from rest_framework.filters import BaseFilterBackend from rest_framework.generics import ListAPIView from rest_framework.pagination import PageNumberPagination from pulseapi.profiles.models import UserProfile from pulseapi.creators.serializers import CreatorSerializer class CreatorsPagination(PageNumberPagination): """ Add support for pagination and custom page size """ # page size decided in https://github.com/mozilla/network-pulse-api/issues/228 page_size = 6 page_size_query_param = 'page_size' max_page_size = 20 class FilterCreatorNameBackend(BaseFilterBackend): def filter_queryset(self, request, queryset, view): search_term = request.query_params.get('name', None) if not search_term: return queryset profile_custom = Q(custom_name__istartswith=search_term) profile_name = Q(related_user__name__istartswith=search_term) istartswith_filter = profile_custom | profile_name qs = queryset.filter(istartswith_filter) # If the number of results returned is less than the allowed # page_size, we can instead rerun this using `contains` rules, # rather than using the `startswith` rule. page_size_query = request.query_params.get('page_size', None) page_size = int(page_size_query if page_size_query else CreatorsPagination.page_size) flen = len(qs) if flen < page_size: profile_custom = Q(custom_name__icontains=search_term) profile_name = Q(related_user__name__icontains=search_term) icontains_filter = profile_custom | profile_name icontains_qs = queryset.filter(icontains_filter).exclude(istartswith_filter) # make sure we keep our exact matches at the top of the result list qs = list(chain(qs, icontains_qs)) return qs class CreatorListView(ListAPIView): """ A view that permits a GET to allow listing all creators in the database Note ---- This view only exists for backwards-compatibility (version 1). Creators no longer exist as independent models and hence the pulseapi.profiles.views.UserProfileListAPIView should be used instead. **Route** - `/creators` #Query Parameters - - ?name= - a partial match filter based on the start of the creator name. """ queryset = UserProfile.objects.active().order_by('id') pagination_class = CreatorsPagination serializer_class = CreatorSerializer filter_backends = ( DjangoFilterBackend, FilterCreatorNameBackend, ) search_fields = ( '^name', ) def get(self, request, *args, **kwargs): if request.version == settings.API_VERSIONS['version_1']: return super().get(request, *args, **kwargs) raise exceptions.NotFound( 'The {path} route has been deprecated and is no longer supported in version {version}'.format( path=request.path, version=request.version ) )