@addon_view_with_unlisted
@non_atomic_requests
def contributions_series(request, addon, group, start, end, format):
    date_range = check_series_params_or_404(group, start, end, format)
    check_stats_permission(request, addon, for_contributions=True)

    # Beware: this needs to scan all the matching rows to do aggregates.
    qs = (Contribution.objects.extra(select={'date_created': 'date(created)'})
          .filter(addon=addon, amount__gt=0, transaction_id__isnull=False,
                  created__range=date_range)
          .values('date_created')
          .annotate(count=Count('amount'), average=Avg('amount'),
                    total=Sum('amount')))

    # Add `date` and `end` keys for legacy compat.
    series = sorted(qs, key=lambda x: x['date_created'], reverse=True)
    for row in series:
        row['end'] = row['date'] = row.pop('date_created')

    if format == 'csv':
        return render_csv(request, addon, series,
                          ['date', 'count', 'total', 'average'])
    elif format == 'json':
        return render_json(request, addon, series)
Moves a model's table between tablespaces
dataset/ETHPy150Open mozilla/addons-server/src/olympia/stats/views.py/contributions_series--crossover with--dataset/ETHPy150Open django/django/django/db/backends/base/schema.py/BaseDatabaseSchemaEditor.alter_db_tablespace