Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class ServiceViewSet(viewsets.ModelViewSet):
- filter_class = ServiceFilter
- is_search = False
- is_preview = False
- # The queryset is only here so DRF knows the base model for this View.
- # We override it below in all cases.
- queryset = Service.objects.select_related(
- 'provider',
- 'type',
- 'region',
- ).prefetch_related('selection_criteria', 'tags', 'types', 'contact_information').all()
- serializer_class = serializers_v2.ServiceSerializer
- pagination_class = StandardResultsSetPagination
- search_fields = ()
- filter_backends = (django_filters.DjangoFilterBackend,
- filters.OrderingFilter, SearchFilter)
- def get_search_fields(self):
- if 'service-management' in self.request.get_full_path():
- return generate_translated_fields('name', False) \
- + generate_translated_fields('type__name', False) \
- + ['region__name'] \
- + ['status']
- else:
- return generate_translated_fields('additional_info', False) \
- + ['cost_of_service'] \
- + generate_translated_fields('description', False) \
- + generate_translated_fields('name', False) \
- + generate_translated_fields('type__comments', False) \
- + generate_translated_fields('type__name', False) \
- + generate_translated_fields('provider__description', False) \
- + generate_translated_fields('provider__focal_point_name', False) \
- + ['provider__focal_point_phone_number'] \
- + generate_translated_fields('provider__address', False) \
- + generate_translated_fields('provider__name', False) \
- + generate_translated_fields('provider__type__name', False) \
- + ['provider__phone_number', 'provider__website', 'provider__user__email'] \
- + generate_translated_fields('selection_criteria__text', False) \
- + ['region__slug', 'tags__name']
- def get_queryset(self):
- # Get filter type
- if self.request.query_params.get('filter') == 'wide':
- self.filter_class = CustomServiceFilter
- elif self.request.query_params.get('filter') == 'relatives':
- self.filter_class = RelativesServiceFilter
- elif self.request.query_params.get('filter') == 'with-parents':
- self.filter_class = WithParentsServiceFilter
- else:
- self.filter_class = ServiceFilter
- # Only make visible the Services owned by the current provider
- if self.is_search:
- qs = self.queryset.filter(status=Service.STATUS_CURRENT).order_by(
- 'location', 'provider__name_en')
- elif self.is_preview:
- qs = self.queryset.filter(
- status__in=[Service.STATUS_CURRENT, Service.STATUS_DRAFT])
- else:
- qs = super().get_queryset()
- self.search_fields = self.get_search_fields()
- if self.request.query_params.get('near'):
- near_query = self.request.query_params.get('near')
- near_km = float(self.request.query_params.get('near_km', '5'))
- point = Point([float(a) for a in near_query.split(',')])
- qs = qs.filter(location__distance_lte=(point, D(km=near_km)))
- if self.request.query_params.get('bounds'):
- bounds_query = self.request.query_params.get('bounds')
- if ';' in bounds_query:
- bounds = [float(a) for x in [b.split(',')
- for b in bounds_query.split(';')] for a in x]
- else:
- bounds = [float(a) for a in bounds_query.split(',')]
- if len(bounds) == 4:
- west, north, east, south = bounds
- poly = Polygon.from_bbox((west, north, east, south))
- qs = qs.filter(location__within=poly)
- return qs
- @list_route(methods=['get'], permission_classes=[AllowAny])
- def search(self, request, *args, **kwargs):
- """
- Public API for searching public information about the current services
- """
- self.is_search = True
- self.serializer_class = serializers_v2.ServiceSearchSerializer
- return super().list(request, *args, **kwargs)
- @list_route(methods=['get'], permission_classes=[AllowAny])
- def preview(self, request, *args, **kwargs):
- """
- Public API for previewing services (for statuses: draft or current)
- """
- self.is_preview = True
- self.serializer_class = serializers_v2.ServiceSearchSerializer
- return super().list(request, *args, **kwargs)
- def get_serializer_class(self):
- if getattr(self, 'action') == 'create':
- return serializers_v2.ServiceCreateSerializer
- if 'service-management' in self.request.get_full_path():
- return serializers_v2.ServiceManagementSerializer
- return serializers_v2.ServiceSerializer
- @detail_route(methods=['post'])
- def push_service_to_transifex(self, request, **kwargs):
- result = push_service_to_transifex(kwargs['pk'])
- return Response(result.info)
- @detail_route(methods=['get'])
- def pull_service_from_transifex(self, request, **kwargs):
- pulled_languages = pull_completed_service_from_transifex(kwargs['pk'])
- return Response(pulled_languages)
- @detail_route(methods=['get'])
- def get_service_transifex_data(self, request, **kwargs):
- r = get_service_transifex_info(kwargs['pk'])
- try:
- transifex_text = json.loads(r.text)
- languages = [i[0] for i in settings.LANGUAGES_CMS]
- output = dict((k, v['completed'])
- for k, v in transifex_text.items() if k in languages)
- except ValueError:
- if r.status_code == 404:
- output = {
- 'errors': 'Service has not been sent to Transifex yet.'
- }
- else:
- output = {
- 'errors': 'An error occurred from Transifex (%s).' % r.text
- }
- return Response(output)
- def partial_update(self, request, *args, **kwargs):
- partial = kwargs.pop('partial', True)
- instance = self.get_object()
- serializer = ServiceImageSerializer(
- instance, data=request.data, partial=partial)
- serializer.is_valid(raise_exception=True)
- self.perform_update(serializer)
- return Response({'status': 204, 'image': settings.MEDIA_URL + str(instance.image.name)})
- @detail_route(methods=['post'])
- def duplicate(self, request, **kwargs):
- service_id = kwargs.get('pk')
- new_name = request.query_params.get('new_name')
- if service_id and new_name:
- service_to_copy = Service.objects.prefetch_related(
- 'tags', 'types').get(id=service_id)
- tags = service_to_copy.tags.all()
- types = service_to_copy.types.all()
- contact_information = service_to_copy.contact_information.all()
- # Clear service data
- service_to_copy.pk = None
- service_to_copy.slug = None
- service_to_copy.name = new_name
- service_to_copy.status = Service.STATUS_DRAFT
- service_to_copy.save()
- # Fill all fragile data
- new_name = re.sub('[\W-]+', '-', new_name.lower())
- new_slug = service_to_copy.region.slug + '_' + \
- str(service_to_copy.provider.id) + '_' + new_name
- services = Service.objects.filter(slug=new_slug)
- if services:
- new_slug = new_slug + '_' + str(service_to_copy.id)
- service_to_copy.slug = new_slug
- service_to_copy.tags.add(*tags)
- service_to_copy.types.add(*types)
- service_to_copy.contact_information.add(*contact_information)
- service_to_copy.save()
- return Response({'service_id': service_to_copy.id}, status=201)
- else:
- return Response({'error': 'Missing service id or service name'}, status=400)
- @detail_route(methods=['post'])
- def archive(self, request, **kwargs):
- service_id = kwargs.get('pk')
- if service_id:
- Service.objects.filter(id=service_id).update(
- status=Service.STATUS_ARCHIVED)
- return Response(None, status=200)
- else:
- return Response({'error': 'Missing service id'}, status=400)
- @detail_route(methods=['get'], permission_classes=[AllowAny])
- def get_same_coordinates_services(self, request, **kwargs):
- requested_service_id = kwargs.get('pk')
- filtered_by_coordinates = []
- max_distance_m = 5
- if requested_service_id:
- requested_service = Service.objects.get(id=requested_service_id)
- if requested_service.location:
- filtered_by_region = self.filter_queryset(self.get_queryset())
- filtered_by_coordinates = filtered_by_region.filter(
- location__distance_lt=(
- requested_service.location, D(m=max_distance_m)),
- status=Service.STATUS_CURRENT) \
- .exclude(id=requested_service_id)
- else:
- return Response({'error': 'Missing service id'}, status=400)
- serializer = serializers_v2.ServiceSerializer(
- filtered_by_coordinates, many=True, context={'request': request})
- return Response({'results': serializer.data}, status=200)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement