def filter_queryset(self, queryset): """ TODO: convert to use proper filter framework """ queryset = super(EventViewSet, self).filter_queryset(queryset) if 'show_all' not in self.request.QUERY_PARAMS: queryset = queryset.filter(Q(event_status=Event.SCHEDULED)) val = self.request.QUERY_PARAMS.get('start', None) if val: dt = parse_time(val, is_start=True) queryset = queryset.filter(Q(end_time__gte=dt) | Q(start_time__gte=dt)) val = self.request.QUERY_PARAMS.get('end', None) if val: dt = parse_time(val, is_start=False) queryset = queryset.filter(Q(end_time__lte=dt) | Q(start_time__lte=dt)) val = self.request.QUERY_PARAMS.get('bbox', None) if val: bbox_filter = build_bbox_filter(self.srs, val, 'location') places = Place.geo_objects.filter(**bbox_filter) queryset = queryset.filter(location__in=places) return queryset
def filter_queryset(self, request, queryset, view): srs = srid_to_srs(request.query_params.get('srid', None)) bbox = request.query_params.get('bbox', None) if bbox: bbox_filter = build_bbox_filter(srs, bbox, 'geometry') queryset = queryset.filter(**bbox_filter) return queryset
def get_queryset(self): queryset = super(UnitViewSet, self).get_queryset() filters = self.request.QUERY_PARAMS if 'id' in filters: id_list = filters['id'].split(',') queryset = queryset.filter(id__in=id_list) if 'municipality' in filters: val = filters['municipality'].lower().strip() if len(val) > 0: municipalities = val.split(',') muni_sq = Q() for municipality_raw in municipalities: municipality = municipality_raw.strip() if municipality.startswith('ocd-division'): ocd_id = municipality else: ocd_id = make_muni_ocd_id(municipality) try: muni = Municipality.objects.get(division__ocd_id=ocd_id) muni_sq |= Q(municipality=muni) except Municipality.DoesNotExist: raise ParseError("municipality with ID '%s' not found" % ocd_id) queryset = queryset.filter(muni_sq) if 'provider_type' in filters: val = filters.get('provider_type') pr_ids = val.split(',') queryset = queryset.filter(provider_type__in=pr_ids) level = filters.get('level', None) level_specs = None if level: if level != 'all': level_specs = settings.LEVELS.get(level) def services_by_ancestors(service_ids): srv_list = set() for srv_id in service_ids: srv_list |= set(Service.objects.all().by_ancestor(srv_id).values_list('id', flat=True)) srv_list.add(int(srv_id)) return list(srv_list) services = filters.get('service', None) service_ids = None if services: services = services.lower() service_ids = services.split(',') elif level_specs: if level_specs['type'] == 'include': service_ids = level_specs['services'] if service_ids: queryset = queryset.filter(services__in=services_by_ancestors(service_ids)).distinct() service_ids = None val = filters.get('exclude_services', None) if val: val = val.lower() service_ids = val.split(',') elif level_specs: if level_specs['type'] == 'exclude': service_ids = level_specs['services'] if service_ids: queryset = queryset.exclude(services__in=services_by_ancestors(service_ids)).distinct() if 'division' in filters: # Divisions can be specified with form: # division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5 d_list = filters['division'].lower().split(',') div_list = [] for division_path in d_list: if division_path.startswith('ocd-division'): muni_ocd_id = division_path else: ocd_id_base = r'[\w0-9~_.-]+' match_re = r'(%s)/([\w_-]+):(%s)' % (ocd_id_base, ocd_id_base) m = re.match(match_re, division_path, re.U) if not m: raise ParseError("'division' must be of form 'muni/type:id'") arr = division_path.split('/') muni_ocd_id = make_muni_ocd_id(arr.pop(0), '/'.join(arr)) try: div = AdministrativeDivision.objects.select_related('geometry').get(ocd_id=muni_ocd_id) except AdministrativeDivision.DoesNotExist: raise ParseError("administrative division with OCD ID '%s' not found" % muni_ocd_id) div_list.append(div) div_geom = [div.geometry.boundary for div in div_list] if div_list: mp = div_list.pop(0).geometry.boundary for div in div_list: mp += div.geometry.boundary queryset = queryset.filter(location__within=mp) if 'lat' in filters and 'lon' in filters: try: lat = float(filters['lat']) lon = float(filters['lon']) except ValueError: raise ParseError("'lat' and 'lon' need to be floating point numbers") point = Point(lon, lat, srid=4326) if 'distance' in filters: try: distance = float(filters['distance']) if not distance > 0: raise ValueError() except ValueError: raise ParseError("'distance' needs to be a floating point number") queryset = queryset.filter(location__distance_lte=(point, distance)) queryset = queryset.distance(point, field_name='geometry').order_by('distance') if 'bbox' in filters: val = self.request.QUERY_PARAMS.get('bbox', None) if 'bbox_srid' in filters: ref = SpatialReference(filters.get('bbox_srid', None)) else: ref = self.srs if val: bbox_filter = munigeo_api.build_bbox_filter(ref, val, 'location') queryset = queryset.filter(**bbox_filter) maintenance_organization = self.request.QUERY_PARAMS.get('maintenance_organization') if maintenance_organization: queryset = queryset.filter( Q(extensions__maintenance_organization=maintenance_organization) | Q(extensions__additional_maintenance_organization=maintenance_organization)) if 'observations' in self.include_fields: queryset = queryset.prefetch_related('observation_set__property__allowed_values').prefetch_related('observation_set__value') if 'connections' in self.include_fields: queryset = queryset.prefetch_related('connections') return queryset
def get_queryset(self): queryset = super(UnitViewSet, self).get_queryset() queryset = queryset.prefetch_related('accessibility_shortcomings') if self._service_details_requested(): queryset = queryset.prefetch_related('service_details') queryset = queryset.prefetch_related('service_details__service') filters = self.request.query_params if 'id' in filters: id_list = filters['id'].split(',') queryset = queryset.filter(id__in=id_list) if 'municipality' in filters: val = filters['municipality'].lower().strip() if len(val) > 0: municipalities = val.split(',') muni_sq = Q() for municipality_raw in municipalities: municipality = municipality_raw.strip() if municipality.startswith('ocd-division'): ocd_id = municipality else: ocd_id = make_muni_ocd_id(municipality) try: muni = Municipality.objects.get( division__ocd_id=ocd_id) muni_sq |= Q(municipality=muni) except Municipality.DoesNotExist: raise ParseError( "municipality with ID '%s' not found" % ocd_id) queryset = queryset.filter(muni_sq) if 'city_as_department' in filters: val = filters['city_as_department'].lower().strip() if len(val) > 0: deps_uuid = val.split(',') deps = Department.objects.filter( uuid__in=deps_uuid).select_related('municipality') munis = [d.municipality for d in deps] queryset = queryset.filter( root_department__in=deps) | queryset.filter( municipality__in=munis) if 'provider_type' in filters: val = filters.get('provider_type') pr_ids = val.split(',') queryset = queryset.filter(provider_type__in=pr_ids) if 'provider_type__not' in filters: val = filters.get('provider_type__not') pr_ids = val.split(',') queryset = queryset.exclude(provider_type__in=pr_ids) level = filters.get('level', None) level_specs = None if level: if level != 'all': level_specs = settings.LEVELS.get(level) def service_nodes_by_ancestors(service_node_ids): srv_list = set() for srv_id in service_node_ids: srv_list |= set( ServiceNode.objects.all().by_ancestor(srv_id).values_list( 'id', flat=True)) srv_list.add(int(srv_id)) return list(srv_list) service_nodes = filters.get('service_node', None) service_node_ids = None if service_nodes: service_nodes = service_nodes.lower() service_node_ids = service_nodes.split(',') elif level_specs: if level_specs['type'] == 'include': service_node_ids = level_specs['service_nodes'] if service_node_ids: queryset = queryset.filter( service_nodes__in=service_nodes_by_ancestors( service_node_ids)).distinct() service_node_ids = None val = filters.get('exclude_service_nodes', None) if val: val = val.lower() service_node_ids = val.split(',') elif level_specs: if level_specs['type'] == 'exclude': service_node_ids = level_specs['service_nodes'] if service_node_ids: queryset = queryset.exclude( service_nodes__in=service_nodes_by_ancestors( service_node_ids)).distinct() services = filters.get('service') if services is not None: queryset = queryset.filter( services__in=services.split(',')).distinct() if 'division' in filters: # Divisions can be specified with form: # division=helsinki/kaupunginosa:kallio,vantaa/äänestysalue:5 d_list = filters['division'].lower().split(',') div_list = [] for division_path in d_list: if division_path.startswith('ocd-division'): muni_ocd_id = division_path else: ocd_id_base = r'[\w0-9~_.-]+' match_re = r'(%s)/([\w_-]+):(%s)' % (ocd_id_base, ocd_id_base) m = re.match(match_re, division_path, re.U) if not m: raise ParseError( "'division' must be of form 'muni/type:id'") arr = division_path.split('/') muni_ocd_id = make_muni_ocd_id(arr.pop(0), '/'.join(arr)) try: div = AdministrativeDivision.objects.select_related( 'geometry').get(ocd_id=muni_ocd_id) except AdministrativeDivision.DoesNotExist: raise ParseError( "administrative division with OCD ID '%s' not found" % muni_ocd_id) div_list.append(div) if div_list: mp = div_list.pop(0).geometry.boundary for div in div_list: mp += div.geometry.boundary queryset = queryset.filter(location__within=mp) if 'lat' in filters and 'lon' in filters: try: lat = float(filters['lat']) lon = float(filters['lon']) except ValueError: raise ParseError( "'lat' and 'lon' need to be floating point numbers") point = Point(lon, lat, srid=4326) if 'distance' in filters: try: distance = float(filters['distance']) if not distance > 0: raise ValueError() except ValueError: raise ParseError( "'distance' needs to be a floating point number") queryset = queryset.filter( location__distance_lte=(point, D(m=distance))) queryset = queryset.annotate( distance=Distance("location", point)).order_by("distance") if 'bbox' in filters: val = self.request.query_params.get('bbox', None) if 'bbox_srid' in filters: ref = SpatialReference(filters.get('bbox_srid', None)) else: ref = self.srs if val: bbox_filter = munigeo_api.build_bbox_filter( ref, val, 'location') bbox_geometry_filter = munigeo_api.build_bbox_filter( ref, val, 'geometry') queryset = queryset.filter( Q(**bbox_filter) | Q(**bbox_geometry_filter)) if 'category' in filters: services_and_service_nodes = filters.get('category', None).split(',') service_ids = [] servicenode_ids = [] for category in services_and_service_nodes: key = category.split(':')[0] value = category.split(':')[1] if key == 'service': service_ids.append(value) elif key == 'service_node': servicenode_ids.append(value) queryset = queryset.filter( Q(services__in=service_ids) | Q(service_nodes__in=service_nodes_by_ancestors( servicenode_ids))).distinct() maintenance_organization = self.request.query_params.get( 'maintenance_organization') if maintenance_organization: queryset = queryset.filter( Q(extensions__maintenance_organization=maintenance_organization ) | Q(extensions__additional_maintenance_organization= maintenance_organization)) if 'observations' in self.include_fields: queryset = queryset.prefetch_related( Prefetch( "observation_set", queryset=Observation.objects.filter( Q(property__expiration=None) | Q(time__gt=timezone.now() - F("property__expiration"))), )).prefetch_related("observation_set__property__allowed_values" ).prefetch_related( "observation_set__value") if 'service_nodes' in self.include_fields: queryset = queryset.prefetch_related('service_nodes') for field in ['connections', 'accessibility_properties', 'keywords']: if self._should_prefetch_field(field): queryset = queryset.prefetch_related(field) return queryset
def _filter_event_queryset(queryset, params, srs=None): """ Filter events queryset by params (e.g. self.request.QUERY_PARAMS in EventViewSet) """ # Filter by string (case insensitive). This searches from all fields # which are marked translatable in translation.py val = params.get('text', None) if val: val = val.lower() # Free string search from all translated fields fields = EventTranslationOptions.fields # and these languages languages = [x[0] for x in settings.LANGUAGES] qset = Q() for field in fields: for lang in languages: kwarg = {field + '_' + lang + '__icontains': val} qset |= Q(**kwarg) queryset = queryset.filter(qset) val = params.get('last_modified_since', None) # This should be in format which dateutil.parser recognizes, e.g. # 2014-10-29T12:00:00Z == 2014-10-29T12:00:00+0000 (UTC time) # or 2014-10-29T12:00:00+0200 (local time) if val: dt = parse_time(val, is_start=False) queryset = queryset.filter(Q(last_modified_time__gte=dt)) val = params.get('start', None) if val: dt = parse_time(val, is_start=True) queryset = queryset.filter(Q(end_time__gt=dt) | Q(start_time__gte=dt)) val = params.get('end', None) if val: dt = parse_time(val, is_start=False) queryset = queryset.filter(Q(end_time__lt=dt) | Q(start_time__lte=dt)) val = params.get('bbox', None) if val: bbox_filter = build_bbox_filter(srs, val, 'position') places = Place.geo_objects.filter(**bbox_filter) queryset = queryset.filter(location__in=places) val = params.get('data_source', None) if val: queryset = queryset.filter(data_source=val) # Filter by location id, multiple ids separated by comma val = params.get('location', None) if val: val = val.split(',') queryset = queryset.filter(location_id__in=val) # Filter by keyword id, multiple ids separated by comma val = params.get('keyword', None) if val: val = val.split(',') queryset = queryset.filter(keywords__pk__in=val) # Filter only super or sub events if recurring has value val = params.get('recurring', None) if val: val = val.lower() if val == 'super': queryset = queryset.filter(is_recurring_super=True) elif val == 'sub': queryset = queryset.filter(is_recurring_super=False) val = params.get('max_duration', None) if val: dur = parse_duration(val) cond = 'end_time - start_time <= %s :: interval' queryset = queryset.extra(where=[cond], params=[str(dur)]) val = params.get('min_duration', None) if val: dur = parse_duration(val) cond = 'end_time - start_time >= %s :: interval' queryset = queryset.extra(where=[cond], params=[str(dur)]) return queryset