diff --git a/apps/projects/helpers.py b/apps/projects/helpers.py index 6b7d90bd8..52f4d2838 100644 --- a/apps/projects/helpers.py +++ b/apps/projects/helpers.py @@ -6,9 +6,6 @@ from django.utils import timezone from adhocracy4.comments.models import Comment -from adhocracy4.polls.models import Answer -from adhocracy4.polls.models import Vote -from adhocracy4.projects.models import Project from adhocracy4.reports.models import Report @@ -44,31 +41,3 @@ def get_num_reported_unread_comments(project): .filter(num_reports__gt=0) .count() ) - - -def get_num_unregistered_participants(project: Project) -> int: - """Returns the number of unregistered users which participated in project. - - Parameters - ---------- - project : The project to get the number for. - """ - - answers = ( - Answer.objects.filter( - question__poll__module__project=project, content_id__isnull=False - ) - .values_list("content_id", flat=True) - .distinct() - .order_by() - ) - votes = ( - Vote.objects.filter( - choice__question__poll__module__project=project, content_id__isnull=False - ) - .exclude(content_id__in=answers) - .values_list("content_id", flat=True) - .distinct() - .order_by() - ) - return len(answers) + len(votes) diff --git a/apps/projects/insights.py b/apps/projects/insights.py index b3330a270..e01f6742a 100644 --- a/apps/projects/insights.py +++ b/apps/projects/insights.py @@ -1,6 +1,8 @@ from typing import Iterable from typing import List +from django.core.exceptions import FieldDoesNotExist + from adhocracy4.polls.models import Answer from adhocracy4.polls.models import Poll from adhocracy4.polls.models import Vote @@ -12,7 +14,6 @@ from apps.interactiveevents.models import LiveQuestion from apps.mapideas.models import MapIdea from apps.projects.helpers import get_all_comments_project -from apps.projects.helpers import get_num_unregistered_participants from apps.projects.models import ProjectInsight from apps.topicprio.models import Topic @@ -27,7 +28,6 @@ def create_insight(project: Project) -> ProjectInsight: ideas = Idea.objects.filter(module__in=modules) map_ideas = MapIdea.objects.filter(module__in=modules) comments = get_all_comments_project(project=project) - unregistered_participants = get_num_unregistered_participants(project=project) proposals = Proposal.objects.filter(module__in=modules) polls = Poll.objects.filter(module__in=modules) votes = Vote.objects.filter(choice__question__poll__in=polls) @@ -68,7 +68,6 @@ def create_insight(project: Project) -> ProjectInsight: insight, _ = ProjectInsight.objects.get_or_create(project=project) insight.comments = comments.count() - insight.unregistered_participants = unregistered_participants insight.ratings = sum(x.count() for x in rating_objects) insight.written_ideas = sum(x.count() for x in idea_objects) insight.poll_answers = votes.count() + answers.count() @@ -76,8 +75,34 @@ def create_insight(project: Project) -> ProjectInsight: insight.save() insight.active_participants.clear() + unregistered_participants = set() + for obj in creator_objects: - ids = list(obj.values_list("creator", flat=True).distinct().order_by()) + # ignore objects which don't have a creator, they are counted in the next step. + ids = list( + obj.filter(creator__isnull=False) + .values_list("creator", flat=True) + .distinct() + .order_by() + ) insight.active_participants.add(*ids) + # content from unregistered users doesn't have a creator but a content_id + if model_field_exists(obj.model, "content_id"): + content_ids = set( + obj.filter(content_id__isnull=False) + .values_list("content_id", flat=True) + .distinct() + .order_by() + ) + unregistered_participants = unregistered_participants.union(content_ids) + insight.unregistered_participants = len(unregistered_participants) return insight + + +def model_field_exists(cls, field): + try: + cls._meta.get_field(field) + return True + except FieldDoesNotExist: + return False