def instructors_over_time(self, request, format=None): """Cumulative number of instructor appearances on workshops over time.""" badges = Badge.objects.instructor_badges() qs = Person.objects.filter(badges__in=badges).annotate( date=Min('award__awarded'), count=Value(1, output_field=IntegerField()) ).order_by('date') filter = InstructorsOverTimeFilter(request.GET, queryset=qs) serializer = InstructorsOverTimeSerializer(filter.qs, many=True) # run a cumulative generator over the data data = accumulate(serializer.data, self._add_counts) # drop data for the same days by showing the last record for # particular date data = self._only_latest_date(data) data = self.listify(data, request, format) return Response(data)
def instructors_over_time(request): '''Export JSON of count of instructors vs. time.''' endpoint = '{}?{}'.format(reverse('api:reports-instructors-over-time'), request.GET.urlencode()) context = { 'api_endpoint': endpoint, 'filter': InstructorsOverTimeFilter(request.GET), 'title': 'Instructors over time', } return render(request, 'reports/time_series.html', context)
def test_badge_non_iterable(self): """Regression test: ensure badges are correctly selected by filter.""" badges = Badge.objects.instructor_badges() qs = Person.objects.annotate( date=Min('award__awarded'), count=Value(1, output_field=IntegerField())).order_by('date') params = QueryDict("badges=1&badges=2") filter_ = InstructorsOverTimeFilter(params, queryset=qs) # would throw an error if the regression is still present self.assertTrue(filter_.qs)