Skip to content

Commit d33766a

Browse files
authored
Improve user stats query (#606)
* Improve user stats query * Update tests
1 parent 1361afb commit d33766a

File tree

4 files changed

+42
-52
lines changed

4 files changed

+42
-52
lines changed

osmchadjango/changeset/serializers.py

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,18 @@ def to_representation(self, data):
9595

9696
reasons_list = [
9797
{'name': reason.name,
98-
'changesets': data.filter(reasons=reason).count(),
99-
'checked_changesets': checked_changesets.filter(reasons=reason).count(),
100-
'harmful_changesets': harmful_changesets.filter(reasons=reason).count(),
101-
}
98+
'changesets': data.filter(reasons=reason).count(),
99+
'checked_changesets': checked_changesets.filter(reasons=reason).count(),
100+
'harmful_changesets': harmful_changesets.filter(reasons=reason).count(),
101+
}
102102
for reason in reasons
103103
]
104104
tags_list = [
105105
{'name': tag.name,
106-
'changesets': data.filter(tags=tag).count(),
107-
'checked_changesets': checked_changesets.filter(tags=tag).count(),
108-
'harmful_changesets': harmful_changesets.filter(tags=tag).count(),
109-
}
106+
'changesets': data.filter(tags=tag).count(),
107+
'checked_changesets': checked_changesets.filter(tags=tag).count(),
108+
'harmful_changesets': harmful_changesets.filter(tags=tag).count(),
109+
}
110110
for tag in tags
111111
]
112112

@@ -131,30 +131,6 @@ class Meta:
131131
list_serializer_class = ChangesetListStatsSerializer
132132

133133

134-
class UserStatsListSerializer(ListSerializer):
135-
read_only = True
136-
137-
def to_representation(self, data):
138-
data = Changeset.objects.filter(id__in=[i.id for i in data])
139-
checked_changesets = data.filter(checked=True)
140-
harmful_changesets = data.filter(harmful=True)
141-
142-
return {
143-
'changesets_in_osmcha': data.count(),
144-
'checked_changesets': checked_changesets.count(),
145-
'harmful_changesets': harmful_changesets.count()
146-
}
147-
148-
@property
149-
def data(self):
150-
return super(ListSerializer, self).data
151-
152-
153-
class UserStatsSerializer(BaseSerializer):
154-
class Meta:
155-
list_serializer_class = UserStatsListSerializer
156-
157-
158134
# the following serializers are used only to validate input data in endpoints
159135
# that check features/changesets or add/remove SuspicionReasons and Tags
160136
class SuspicionReasonsChangesetSerializer(ModelSerializer):

osmchadjango/changeset/tests/test_stats_views.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -183,16 +183,14 @@ def test_user_one_stats(self):
183183
self.client.login(username=self.user.username, password='password')
184184
response = self.client.get(reverse('changeset:user-stats', args=['4321']))
185185
self.assertEqual(response.status_code, 200)
186-
results = response.data.get('results')
187-
self.assertEqual(results.get('changesets_in_osmcha'), 3)
188-
self.assertEqual(results.get('checked_changesets'), 2)
189-
self.assertEqual(results.get('harmful_changesets'), 1)
186+
self.assertEqual(response.data.get('changesets_in_osmcha'), 3)
187+
self.assertEqual(response.data.get('checked_changesets'), 2)
188+
self.assertEqual(response.data.get('harmful_changesets'), 1)
190189

191190
def test_user_without_changesets(self):
192191
self.client.login(username=self.user.username, password='password')
193192
response = self.client.get(reverse('changeset:user-stats', args=['1611']))
194193
self.assertEqual(response.status_code, 200)
195-
results = response.data.get('results')
196-
self.assertEqual(results.get('changesets_in_osmcha'), 0)
197-
self.assertEqual(results.get('checked_changesets'), 0)
198-
self.assertEqual(results.get('harmful_changesets'), 0)
194+
self.assertEqual(response.data.get('changesets_in_osmcha'), 0)
195+
self.assertEqual(response.data.get('checked_changesets'), 0)
196+
self.assertEqual(response.data.get('harmful_changesets'), 0)

osmchadjango/changeset/urls.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,9 @@
130130
view=views.ChangesetStatsAPIView.as_view(),
131131
name='stats'
132132
),
133-
re_path(
134-
r'^user-stats/(?P<uid>\w+)/$',
135-
view=views.UserStatsAPIView.as_view(),
133+
path(
134+
'user-stats/<int:uid>/',
135+
view=views.user_stats,
136136
name='user-stats'
137137
),
138138
]

osmchadjango/changeset/views.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from django.utils import timezone
55
from django.utils.translation import ugettext, ugettext_lazy as _
66
from django.db.utils import IntegrityError
7+
from django.db import connection
78
from django.conf import settings
89

910
import django_filters.rest_framework
@@ -30,7 +31,7 @@
3031
from .serializers import (
3132
ChangesetSerializer, ChangesetSerializerToStaff, ChangesetStatsSerializer,
3233
ChangesetTagsSerializer, SuspicionReasonsChangesetSerializer,
33-
SuspicionReasonsSerializer, UserStatsSerializer, UserWhitelistSerializer,
34+
SuspicionReasonsSerializer, UserWhitelistSerializer,
3435
TagSerializer, ChangesetCommentSerializer, ReviewedFeatureSerializer
3536
)
3637
from .tasks import ChangesetCommentAPI
@@ -537,15 +538,29 @@ class ChangesetStatsAPIView(ListAPIView):
537538
filter_class = ChangesetFilter
538539

539540

540-
class UserStatsAPIView(ListAPIView):
541-
"""Get stats about an OSM user in the OSMCHA history. It needs to receive
542-
the uid of the user in OSM.
541+
@api_view(['GET'])
542+
@permission_classes((IsAuthenticated,))
543+
def user_stats(request, uid):
544+
"""Get stats about an OSM user in the OSMCHA history.
545+
It needs to receive the uid of the user in OSM.
543546
"""
544-
serializer_class = UserStatsSerializer
545-
permission_classes = (IsAuthenticated,)
546-
547-
def get_queryset(self):
548-
return Changeset.objects.filter(uid=self.kwargs['uid'])
547+
query = """
548+
SELECT
549+
count(*),
550+
count(*) filter (where checked),
551+
count(*) filter (where harmful)
552+
FROM changeset_changeset
553+
WHERE uid = %s
554+
"""
555+
with connection.cursor() as cursor:
556+
cursor.execute(query, [str(uid)])
557+
total, checked, harmful = cursor.fetchone()
558+
instance = {
559+
"changesets_in_osmcha": total,
560+
"checked_changesets": checked,
561+
"harmful_changesets": harmful
562+
}
563+
return Response(instance)
549564

550565

551566
class ChangesetCommentAPIView(ModelViewSet):
@@ -683,6 +698,7 @@ class SetChangesetTagChangesAPIView(ModelViewSet):
683698
@action(detail=True, methods=['post'])
684699
def set_tag_changes(self, request, pk):
685700
"""Update the tag_changes field of a Changeset"""
701+
print(self.request.data)
686702
if self.validate_tag_changes(self.request.data) is False:
687703
return Response(
688704
{'detail': 'Payload does not match validation rules.'},

0 commit comments

Comments
 (0)