Skip to content

Commit ffb8555

Browse files
Address PR feedback: move view counting logic to PublishedProject model
1 parent c3d7275 commit ffb8555

File tree

2 files changed

+65
-40
lines changed

2 files changed

+65
-40
lines changed

physionet-django/project/modelcomponents/publishedproject.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from distutils.version import StrictVersion
55

66
from django.conf import settings
7+
from django.contrib.contenttypes.models import ContentType
78
from django.db import models
89
from django.urls import reverse
910
from django.utils import timezone
@@ -385,3 +386,60 @@ def get_all_news(self):
385386
link_all_versions=True).exclude(project=self)
386387

387388
return direct_news | linked_news
389+
390+
def view_count(self, all_versions=False):
391+
"""
392+
Return the count of unique registered users who have viewed this project.
393+
394+
Args:
395+
all_versions: If True, count views across all versions of this project.
396+
If False (default), count only views of this specific version.
397+
"""
398+
from project.models import AccessLog
399+
400+
if all_versions:
401+
versions = PublishedProject.objects.filter(slug=self.slug)
402+
total = 0
403+
for v in versions:
404+
content_type = ContentType.objects.get_for_model(v)
405+
total += AccessLog.objects.filter(
406+
object_id=v.id,
407+
content_type=content_type
408+
).unique_viewers_count()
409+
return total
410+
else:
411+
content_type = ContentType.objects.get_for_model(self)
412+
return AccessLog.objects.filter(
413+
object_id=self.id,
414+
content_type=content_type
415+
).unique_viewers_count()
416+
417+
def views_by_version(self):
418+
"""
419+
Return a list of view counts for each version of this project.
420+
"""
421+
from project.models import AccessLog
422+
423+
versions = PublishedProject.objects.filter(slug=self.slug).order_by('version_order')
424+
result = []
425+
for v in versions:
426+
content_type = ContentType.objects.get_for_model(v)
427+
count = AccessLog.objects.filter(
428+
object_id=v.id,
429+
content_type=content_type
430+
).unique_viewers_count()
431+
result.append({'version': v.version, 'count': count})
432+
return result
433+
434+
def views_over_time(self):
435+
"""
436+
Return monthly view counts for this project version.
437+
Each user is only counted in the month of their first view.
438+
"""
439+
from project.models import AccessLog
440+
441+
content_type = ContentType.objects.get_for_model(self)
442+
return AccessLog.objects.filter(
443+
object_id=self.id,
444+
content_type=content_type
445+
).first_views_by_month()

physionet-django/project/views.py

Lines changed: 7 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2013,17 +2013,8 @@ def published_project(request, project_slug, version, subdir=''):
20132013
except AWS.DoesNotExist:
20142014
user_in_access_point_policy = False
20152015

2016-
content_type = ContentType.objects.get_for_model(project)
2017-
project_views_count = AccessLog.objects.filter(
2018-
object_id=project.id,
2019-
content_type=content_type
2020-
).values('user').distinct().count()
2021-
2022-
all_version_ids = PublishedProject.objects.filter(slug=project_slug).values_list('id', flat=True)
2023-
all_versions_views_count = AccessLog.objects.filter(
2024-
object_id__in=all_version_ids,
2025-
content_type=content_type
2026-
).values('user').distinct().count()
2016+
project_views_count = project.view_count()
2017+
all_versions_views_count = project.view_count(all_versions=True)
20272018

20282019
context = {
20292020
'project': project,
@@ -2112,38 +2103,14 @@ def published_project_metrics(request, project_slug, version):
21122103
"""
21132104
Public metrics page for a published project.
21142105
"""
2115-
from django.db.models import Count
2116-
from django.db.models.functions import TruncMonth
2117-
2118-
try:
2119-
project = PublishedProject.objects.get(slug=project_slug, version=version)
2120-
except ObjectDoesNotExist:
2121-
raise Http404()
2122-
2123-
content_type = ContentType.objects.get_for_model(project)
2124-
2125-
project_logs = AccessLog.objects.filter(object_id=project.id, content_type=content_type)
2126-
project_views_count = project_logs.unique_viewers_count()
2127-
views_over_time = project_logs.first_views_by_month()
2128-
2129-
all_versions = PublishedProject.objects.filter(slug=project_slug).order_by('version_order')
2130-
views_by_version = []
2131-
all_versions_views_count = 0
2132-
for v in all_versions:
2133-
v_content_type = ContentType.objects.get_for_model(v)
2134-
v_count = AccessLog.objects.filter(
2135-
object_id=v.id,
2136-
content_type=v_content_type
2137-
).unique_viewers_count()
2138-
views_by_version.append({'version': v.version, 'count': v_count})
2139-
all_versions_views_count += v_count
2106+
project = get_object_or_404(PublishedProject, slug=project_slug, version=version)
21402107

21412108
return render(request, 'project/published_project_metrics.html', {
21422109
'project': project,
2143-
'project_views_count': project_views_count,
2144-
'all_versions_views_count': all_versions_views_count,
2145-
'views_over_time': views_over_time,
2146-
'views_by_version': views_by_version,
2110+
'project_views_count': project.view_count(),
2111+
'all_versions_views_count': project.view_count(all_versions=True),
2112+
'views_over_time': project.views_over_time(),
2113+
'views_by_version': project.views_by_version(),
21472114
})
21482115

21492116

0 commit comments

Comments
 (0)