def parse(self, widget_options, site): aktivitet_dates = AktivitetDate.get_published().filter( Q(aktivitet__forening__in=widget_options['foreninger']) | Q(aktivitet__co_foreninger__in=widget_options['foreninger']), aktivitet__private=False, start_date__gte=date.today(), ) url_query_parameters = [] limit = widget_options.get('limit', 50) total = aktivitet_dates.count() more_activities_count = total - limit # Skip if none, or all, audiences were chosen if len(widget_options['audiences']) > 0 and len(widget_options['audiences']) < len(AktivitetAudience.AUDIENCE_CHOICES): aktivitet_dates = aktivitet_dates.filter(aktivitet__audiences__name__in=widget_options['audiences']) url_query_parameters.append("audiences=%s" % ",".join(widget_options['audiences'])) # Skip if none, or all, categories were chosen if len(widget_options['categories']) > 0 and len(widget_options['categories']) < len(Aktivitet.CATEGORY_CHOICES): aktivitet_dates = aktivitet_dates.filter( aktivitet__category__in=widget_options['categories'], ) url_query_parameters.append("categories=%s" % ",".join(widget_options['categories'])) if len(widget_options['foreninger']) > 0: organizers = ["forening:%s" % f for f in widget_options['foreninger']] url_query_parameters.append("organizers=%s" % ",".join(organizers)) aktivitet_dates = aktivitet_dates.order_by('start_date')[:limit] see_more_query_params = "&".join(url_query_parameters) return { 'aktivitet_dates': aktivitet_dates, 'see_more_query_params': see_more_query_params, 'total': total, 'limit': limit, 'more_activities_count': more_activities_count }
def filter_aktivitet_dates(filter): # To the next mainainer: The filter param is a mutateable query dict such that this util method # can split strings into lists which the template logic is dependent upon. If you find a better # way, please refactor this code. dates = AktivitetDate.get_published().select_related( 'aktivitet__forening', ).prefetch_related( 'aktivitet', 'aktivitet__images', 'aktivitet__forening__sites', 'aktivitet__co_foreninger', ).filter(aktivitet__private=False) if filter.get('search', '') and len(filter['search'].strip()) > 2: words = filter['search'].split() dates = dates.filter( Q(reduce(lambda x, y: x & y, [Q(aktivitet__title__icontains=word) | Q(aktivitet__description__icontains=word) for word in words])) | Q(aktivitet__code=filter['search']) ) if filter.get('omrader', ''): filter['omrader'] = filter['omrader'].split(',') for omrade in filter['omrader']: dates = dates.extra( where=['%s = ANY ("{0}"."omrader")'.format(Aktivitet._meta.db_table)], params=[omrade], ) if filter.get('categories', ''): filter['categories'] = filter['categories'].split(',') dates = dates.filter(aktivitet__category__in=filter['categories']) if filter.get('category_types', ''): filter['category_types'] = filter['category_types'].split(',') # Note that we're checking for both types and tags, and since objects may have the same tag specified twice, # it'll require an explicit distinct clause in our query dates = dates.filter( Q(aktivitet__category_type__in=filter['category_types']) | Q(aktivitet__category_tags__name__in=filter['category_types']) ) if filter.get('audiences', ''): filter['audiences'] = filter['audiences'].split(',') dates = dates.filter(aktivitet__audiences__name__in=filter['audiences']) if filter.get('difficulties', ''): filter['difficulties'] = filter['difficulties'].split(',') dates = dates.filter(aktivitet__difficulty__in=filter['difficulties']) if filter.get('lat_lng', '') and len(filter['lat_lng'].split(',')) == 2: filter['lat_lng'] = filter['lat_lng'].split(',') # Rule of thumb for buffer; 1 degree is about 100 km boundary = geos.Point(float(filter['lat_lng'][0]), float(filter['lat_lng'][1])).buffer(0.5) dates = dates.filter(aktivitet__start_point__within=boundary) # @TODO refactor to make use of django range query # https://docs.djangoproject.com/en/dev/ref/models/querysets/#range try: if filter.get('start_date', ''): dates = dates.filter(start_date__gte=datetime.strptime(filter['start_date'], "%d.%m.%Y")) else: today = date.today() dates = dates.filter(start_date__gte=datetime(today.year, today.month, today.day)) if filter.get('end_date'): dates = dates.filter(end_date__lte=datetime.strptime(filter['end_date'], "%d.%m.%Y")) except (ValueError, KeyError): pass if filter.get('organizers', ''): filter['organizers'] = filter['organizers'].split(',') filter['foreninger'] = [] filter['cabins'] = [] for organizer in filter['organizers']: try: type, id = organizer.split(':') if type == 'forening': filter['foreninger'].append(int(id)) elif type == 'cabin': filter['cabins'].append(int(id)) except ValueError: continue if filter['foreninger']: dates = dates.filter( Q(aktivitet__forening__in=filter['foreninger']) | Q(aktivitet__co_foreninger__in=filter['foreninger']) ) if filter['cabins']: dates = dates.filter( Q(aktivitet__forening_cabin__in=filter['cabins']) | Q(aktivitet__co_foreninger_cabin__in=filter['cabins']) ) dates = dates.distinct().order_by( 'start_date' ) return filter, dates