From d33766a4a881b63d3fba10fe8c3334368abf8237 Mon Sep 17 00:00:00 2001 From: Wille Marcel Date: Fri, 13 May 2022 09:36:42 -0300 Subject: [PATCH] Improve user stats query (#606) * Improve user stats query * Update tests --- osmchadjango/changeset/serializers.py | 40 ++++--------------- .../changeset/tests/test_stats_views.py | 14 +++---- osmchadjango/changeset/urls.py | 6 +-- osmchadjango/changeset/views.py | 34 +++++++++++----- 4 files changed, 42 insertions(+), 52 deletions(-) diff --git a/osmchadjango/changeset/serializers.py b/osmchadjango/changeset/serializers.py index 8dccfe47..54ea46ee 100644 --- a/osmchadjango/changeset/serializers.py +++ b/osmchadjango/changeset/serializers.py @@ -95,18 +95,18 @@ def to_representation(self, data): reasons_list = [ {'name': reason.name, - 'changesets': data.filter(reasons=reason).count(), - 'checked_changesets': checked_changesets.filter(reasons=reason).count(), - 'harmful_changesets': harmful_changesets.filter(reasons=reason).count(), - } + 'changesets': data.filter(reasons=reason).count(), + 'checked_changesets': checked_changesets.filter(reasons=reason).count(), + 'harmful_changesets': harmful_changesets.filter(reasons=reason).count(), + } for reason in reasons ] tags_list = [ {'name': tag.name, - 'changesets': data.filter(tags=tag).count(), - 'checked_changesets': checked_changesets.filter(tags=tag).count(), - 'harmful_changesets': harmful_changesets.filter(tags=tag).count(), - } + 'changesets': data.filter(tags=tag).count(), + 'checked_changesets': checked_changesets.filter(tags=tag).count(), + 'harmful_changesets': harmful_changesets.filter(tags=tag).count(), + } for tag in tags ] @@ -131,30 +131,6 @@ class Meta: list_serializer_class = ChangesetListStatsSerializer -class UserStatsListSerializer(ListSerializer): - read_only = True - - def to_representation(self, data): - data = Changeset.objects.filter(id__in=[i.id for i in data]) - checked_changesets = data.filter(checked=True) - harmful_changesets = data.filter(harmful=True) - - return { - 'changesets_in_osmcha': data.count(), - 'checked_changesets': checked_changesets.count(), - 'harmful_changesets': harmful_changesets.count() - } - - @property - def data(self): - return super(ListSerializer, self).data - - -class UserStatsSerializer(BaseSerializer): - class Meta: - list_serializer_class = UserStatsListSerializer - - # the following serializers are used only to validate input data in endpoints # that check features/changesets or add/remove SuspicionReasons and Tags class SuspicionReasonsChangesetSerializer(ModelSerializer): diff --git a/osmchadjango/changeset/tests/test_stats_views.py b/osmchadjango/changeset/tests/test_stats_views.py index 8b767304..a0665bf1 100644 --- a/osmchadjango/changeset/tests/test_stats_views.py +++ b/osmchadjango/changeset/tests/test_stats_views.py @@ -183,16 +183,14 @@ def test_user_one_stats(self): self.client.login(username=self.user.username, password='password') response = self.client.get(reverse('changeset:user-stats', args=['4321'])) self.assertEqual(response.status_code, 200) - results = response.data.get('results') - self.assertEqual(results.get('changesets_in_osmcha'), 3) - self.assertEqual(results.get('checked_changesets'), 2) - self.assertEqual(results.get('harmful_changesets'), 1) + self.assertEqual(response.data.get('changesets_in_osmcha'), 3) + self.assertEqual(response.data.get('checked_changesets'), 2) + self.assertEqual(response.data.get('harmful_changesets'), 1) def test_user_without_changesets(self): self.client.login(username=self.user.username, password='password') response = self.client.get(reverse('changeset:user-stats', args=['1611'])) self.assertEqual(response.status_code, 200) - results = response.data.get('results') - self.assertEqual(results.get('changesets_in_osmcha'), 0) - self.assertEqual(results.get('checked_changesets'), 0) - self.assertEqual(results.get('harmful_changesets'), 0) + self.assertEqual(response.data.get('changesets_in_osmcha'), 0) + self.assertEqual(response.data.get('checked_changesets'), 0) + self.assertEqual(response.data.get('harmful_changesets'), 0) diff --git a/osmchadjango/changeset/urls.py b/osmchadjango/changeset/urls.py index 05324079..101d1db5 100644 --- a/osmchadjango/changeset/urls.py +++ b/osmchadjango/changeset/urls.py @@ -130,9 +130,9 @@ view=views.ChangesetStatsAPIView.as_view(), name='stats' ), - re_path( - r'^user-stats/(?P\w+)/$', - view=views.UserStatsAPIView.as_view(), + path( + 'user-stats//', + view=views.user_stats, name='user-stats' ), ] diff --git a/osmchadjango/changeset/views.py b/osmchadjango/changeset/views.py index 582397eb..63e0c42a 100644 --- a/osmchadjango/changeset/views.py +++ b/osmchadjango/changeset/views.py @@ -4,6 +4,7 @@ from django.utils import timezone from django.utils.translation import ugettext, ugettext_lazy as _ from django.db.utils import IntegrityError +from django.db import connection from django.conf import settings import django_filters.rest_framework @@ -30,7 +31,7 @@ from .serializers import ( ChangesetSerializer, ChangesetSerializerToStaff, ChangesetStatsSerializer, ChangesetTagsSerializer, SuspicionReasonsChangesetSerializer, - SuspicionReasonsSerializer, UserStatsSerializer, UserWhitelistSerializer, + SuspicionReasonsSerializer, UserWhitelistSerializer, TagSerializer, ChangesetCommentSerializer, ReviewedFeatureSerializer ) from .tasks import ChangesetCommentAPI @@ -537,15 +538,29 @@ class ChangesetStatsAPIView(ListAPIView): filter_class = ChangesetFilter -class UserStatsAPIView(ListAPIView): - """Get stats about an OSM user in the OSMCHA history. It needs to receive - the uid of the user in OSM. +@api_view(['GET']) +@permission_classes((IsAuthenticated,)) +def user_stats(request, uid): + """Get stats about an OSM user in the OSMCHA history. + It needs to receive the uid of the user in OSM. """ - serializer_class = UserStatsSerializer - permission_classes = (IsAuthenticated,) - - def get_queryset(self): - return Changeset.objects.filter(uid=self.kwargs['uid']) + query = """ + SELECT + count(*), + count(*) filter (where checked), + count(*) filter (where harmful) + FROM changeset_changeset + WHERE uid = %s + """ + with connection.cursor() as cursor: + cursor.execute(query, [str(uid)]) + total, checked, harmful = cursor.fetchone() + instance = { + "changesets_in_osmcha": total, + "checked_changesets": checked, + "harmful_changesets": harmful + } + return Response(instance) class ChangesetCommentAPIView(ModelViewSet): @@ -683,6 +698,7 @@ class SetChangesetTagChangesAPIView(ModelViewSet): @action(detail=True, methods=['post']) def set_tag_changes(self, request, pk): """Update the tag_changes field of a Changeset""" + print(self.request.data) if self.validate_tag_changes(self.request.data) is False: return Response( {'detail': 'Payload does not match validation rules.'},