Advertisement
Guest User

queryset

a guest
Sep 24th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.59 KB | None | 0 0
  1. class ServiceViewSet(viewsets.ModelViewSet):
  2. filter_class = ServiceFilter
  3. is_search = False
  4. is_preview = False
  5.  
  6. # The queryset is only here so DRF knows the base model for this View.
  7. # We override it below in all cases.
  8. queryset = Service.objects.select_related(
  9. 'provider',
  10. 'type',
  11. 'region',
  12. ).prefetch_related('selection_criteria', 'tags', 'types', 'contact_information').all()
  13.  
  14. serializer_class = serializers_v2.ServiceSerializer
  15. pagination_class = StandardResultsSetPagination
  16. search_fields = ()
  17. filter_backends = (django_filters.DjangoFilterBackend,
  18. filters.OrderingFilter, SearchFilter)
  19.  
  20. def get_search_fields(self):
  21. if 'service-management' in self.request.get_full_path():
  22. return generate_translated_fields('name', False) \
  23. + generate_translated_fields('type__name', False) \
  24. + ['region__name'] \
  25. + ['status']
  26. else:
  27. return generate_translated_fields('additional_info', False) \
  28. + ['cost_of_service'] \
  29. + generate_translated_fields('description', False) \
  30. + generate_translated_fields('name', False) \
  31. + generate_translated_fields('type__comments', False) \
  32. + generate_translated_fields('type__name', False) \
  33. + generate_translated_fields('provider__description', False) \
  34. + generate_translated_fields('provider__focal_point_name', False) \
  35. + ['provider__focal_point_phone_number'] \
  36. + generate_translated_fields('provider__address', False) \
  37. + generate_translated_fields('provider__name', False) \
  38. + generate_translated_fields('provider__type__name', False) \
  39. + ['provider__phone_number', 'provider__website', 'provider__user__email'] \
  40. + generate_translated_fields('selection_criteria__text', False) \
  41. + ['region__slug', 'tags__name']
  42.  
  43. def get_queryset(self):
  44. # Get filter type
  45. if self.request.query_params.get('filter') == 'wide':
  46. self.filter_class = CustomServiceFilter
  47. elif self.request.query_params.get('filter') == 'relatives':
  48. self.filter_class = RelativesServiceFilter
  49. elif self.request.query_params.get('filter') == 'with-parents':
  50. self.filter_class = WithParentsServiceFilter
  51. else:
  52. self.filter_class = ServiceFilter
  53.  
  54. # Only make visible the Services owned by the current provider
  55. if self.is_search:
  56. qs = self.queryset.filter(status=Service.STATUS_CURRENT).order_by(
  57. 'location', 'provider__name_en')
  58. elif self.is_preview:
  59. qs = self.queryset.filter(
  60. status__in=[Service.STATUS_CURRENT, Service.STATUS_DRAFT])
  61. else:
  62. qs = super().get_queryset()
  63. self.search_fields = self.get_search_fields()
  64.  
  65. if self.request.query_params.get('near'):
  66. near_query = self.request.query_params.get('near')
  67. near_km = float(self.request.query_params.get('near_km', '5'))
  68. point = Point([float(a) for a in near_query.split(',')])
  69.  
  70. qs = qs.filter(location__distance_lte=(point, D(km=near_km)))
  71.  
  72. if self.request.query_params.get('bounds'):
  73. bounds_query = self.request.query_params.get('bounds')
  74. if ';' in bounds_query:
  75. bounds = [float(a) for x in [b.split(',')
  76. for b in bounds_query.split(';')] for a in x]
  77. else:
  78. bounds = [float(a) for a in bounds_query.split(',')]
  79.  
  80. if len(bounds) == 4:
  81. west, north, east, south = bounds
  82. poly = Polygon.from_bbox((west, north, east, south))
  83. qs = qs.filter(location__within=poly)
  84.  
  85. return qs
  86.  
  87. @list_route(methods=['get'], permission_classes=[AllowAny])
  88. def search(self, request, *args, **kwargs):
  89. """
  90. Public API for searching public information about the current services
  91. """
  92. self.is_search = True
  93. self.serializer_class = serializers_v2.ServiceSearchSerializer
  94. return super().list(request, *args, **kwargs)
  95.  
  96. @list_route(methods=['get'], permission_classes=[AllowAny])
  97. def preview(self, request, *args, **kwargs):
  98. """
  99. Public API for previewing services (for statuses: draft or current)
  100. """
  101. self.is_preview = True
  102. self.serializer_class = serializers_v2.ServiceSearchSerializer
  103. return super().list(request, *args, **kwargs)
  104.  
  105. def get_serializer_class(self):
  106. if getattr(self, 'action') == 'create':
  107. return serializers_v2.ServiceCreateSerializer
  108. if 'service-management' in self.request.get_full_path():
  109. return serializers_v2.ServiceManagementSerializer
  110. return serializers_v2.ServiceSerializer
  111.  
  112. @detail_route(methods=['post'])
  113. def push_service_to_transifex(self, request, **kwargs):
  114. result = push_service_to_transifex(kwargs['pk'])
  115. return Response(result.info)
  116.  
  117. @detail_route(methods=['get'])
  118. def pull_service_from_transifex(self, request, **kwargs):
  119. pulled_languages = pull_completed_service_from_transifex(kwargs['pk'])
  120. return Response(pulled_languages)
  121.  
  122. @detail_route(methods=['get'])
  123. def get_service_transifex_data(self, request, **kwargs):
  124. r = get_service_transifex_info(kwargs['pk'])
  125. try:
  126. transifex_text = json.loads(r.text)
  127. languages = [i[0] for i in settings.LANGUAGES_CMS]
  128. output = dict((k, v['completed'])
  129. for k, v in transifex_text.items() if k in languages)
  130. except ValueError:
  131. if r.status_code == 404:
  132. output = {
  133. 'errors': 'Service has not been sent to Transifex yet.'
  134. }
  135. else:
  136. output = {
  137. 'errors': 'An error occurred from Transifex (%s).' % r.text
  138. }
  139.  
  140. return Response(output)
  141.  
  142. def partial_update(self, request, *args, **kwargs):
  143. partial = kwargs.pop('partial', True)
  144. instance = self.get_object()
  145. serializer = ServiceImageSerializer(
  146. instance, data=request.data, partial=partial)
  147. serializer.is_valid(raise_exception=True)
  148. self.perform_update(serializer)
  149. return Response({'status': 204, 'image': settings.MEDIA_URL + str(instance.image.name)})
  150.  
  151. @detail_route(methods=['post'])
  152. def duplicate(self, request, **kwargs):
  153. service_id = kwargs.get('pk')
  154. new_name = request.query_params.get('new_name')
  155. if service_id and new_name:
  156. service_to_copy = Service.objects.prefetch_related(
  157. 'tags', 'types').get(id=service_id)
  158. tags = service_to_copy.tags.all()
  159. types = service_to_copy.types.all()
  160. contact_information = service_to_copy.contact_information.all()
  161. # Clear service data
  162. service_to_copy.pk = None
  163. service_to_copy.slug = None
  164. service_to_copy.name = new_name
  165. service_to_copy.status = Service.STATUS_DRAFT
  166. service_to_copy.save()
  167. # Fill all fragile data
  168. new_name = re.sub('[\W-]+', '-', new_name.lower())
  169. new_slug = service_to_copy.region.slug + '_' + \
  170. str(service_to_copy.provider.id) + '_' + new_name
  171. services = Service.objects.filter(slug=new_slug)
  172. if services:
  173. new_slug = new_slug + '_' + str(service_to_copy.id)
  174. service_to_copy.slug = new_slug
  175. service_to_copy.tags.add(*tags)
  176. service_to_copy.types.add(*types)
  177. service_to_copy.contact_information.add(*contact_information)
  178. service_to_copy.save()
  179. return Response({'service_id': service_to_copy.id}, status=201)
  180. else:
  181. return Response({'error': 'Missing service id or service name'}, status=400)
  182.  
  183. @detail_route(methods=['post'])
  184. def archive(self, request, **kwargs):
  185. service_id = kwargs.get('pk')
  186. if service_id:
  187. Service.objects.filter(id=service_id).update(
  188. status=Service.STATUS_ARCHIVED)
  189. return Response(None, status=200)
  190. else:
  191. return Response({'error': 'Missing service id'}, status=400)
  192.  
  193. @detail_route(methods=['get'], permission_classes=[AllowAny])
  194. def get_same_coordinates_services(self, request, **kwargs):
  195. requested_service_id = kwargs.get('pk')
  196. filtered_by_coordinates = []
  197. max_distance_m = 5
  198. if requested_service_id:
  199. requested_service = Service.objects.get(id=requested_service_id)
  200. if requested_service.location:
  201. filtered_by_region = self.filter_queryset(self.get_queryset())
  202. filtered_by_coordinates = filtered_by_region.filter(
  203. location__distance_lt=(
  204. requested_service.location, D(m=max_distance_m)),
  205. status=Service.STATUS_CURRENT) \
  206. .exclude(id=requested_service_id)
  207. else:
  208. return Response({'error': 'Missing service id'}, status=400)
  209.  
  210. serializer = serializers_v2.ServiceSerializer(
  211. filtered_by_coordinates, many=True, context={'request': request})
  212. return Response({'results': serializer.data}, status=200)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement