diff --git a/recoco/apps/hitcount/managers.py b/recoco/apps/hitcount/managers.py new file mode 100644 index 000000000..72144bb1f --- /dev/null +++ b/recoco/apps/hitcount/managers.py @@ -0,0 +1,19 @@ +from django.contrib.contenttypes.models import ContentType +from django.db import models + + +class HitCountQuerySet(models.QuerySet): + def for_content_object(self, content_object) -> models.QuerySet: + content_type = ContentType.objects.get_for_model(content_object) + return self.filter( + content_object_ct=content_type, content_object_id=content_object.pk + ) + + def for_context_object(self, context_object) -> models.QuerySet: + content_type = ContentType.objects.get_for_model(context_object) + return self.filter( + context_object_ct=content_type, context_object_id=context_object.pk + ) + + def for_user(self, user) -> models.QuerySet: + return self.filter(hits__user=user) diff --git a/recoco/apps/hitcount/models.py b/recoco/apps/hitcount/models.py index 72a037588..8e08dbcd9 100644 --- a/recoco/apps/hitcount/models.py +++ b/recoco/apps/hitcount/models.py @@ -6,6 +6,8 @@ from django.utils.translation import gettext_lazy as _ from model_utils.models import TimeStampedModel +from .managers import HitCountQuerySet + class HitCount(TimeStampedModel): site = models.ForeignKey(Site, on_delete=models.CASCADE) @@ -28,6 +30,8 @@ class HitCount(TimeStampedModel): context_object_id = models.PositiveIntegerField(null=True, blank=True) context_object = GenericForeignKey("context_object_ct", "context_object_id") + objects = HitCountQuerySet.as_manager() + class Meta: verbose_name = _("hit count") verbose_name_plural = _("hit counts") diff --git a/recoco/apps/hitcount/tests/test_managers.py b/recoco/apps/hitcount/tests/test_managers.py new file mode 100644 index 000000000..67820943f --- /dev/null +++ b/recoco/apps/hitcount/tests/test_managers.py @@ -0,0 +1,52 @@ +import pytest +from django.contrib.auth.models import User +from model_bakery import baker + +from recoco.apps.addressbook.models import Contact +from recoco.apps.hitcount.models import Hit, HitCount +from recoco.apps.projects.models import Project +from recoco.apps.tasks.models import Task + + +@pytest.mark.django_db +def test_manager(): + contact = baker.make(Contact) + project = baker.make(Project) + resource = baker.make(Task) + + user_1 = baker.make(User) + user_2 = baker.make(User) + + hitcount_contact_project = baker.make( + HitCount, content_object=contact, context_object=project + ) + baker.make(Hit, hitcount=hitcount_contact_project, user=user_1) + baker.make(Hit, hitcount=hitcount_contact_project, user=user_2) + + hitcount_contact_resource = baker.make( + HitCount, content_object=contact, context_object=resource + ) + baker.make(Hit, hitcount=hitcount_contact_resource, user=user_1) + + assert HitCount.objects.for_content_object(contact).count() == 2 + + queryset = HitCount.objects.for_context_object(project) + assert queryset.count() == 1 + assert queryset.first() == hitcount_contact_project + + queryset = HitCount.objects.for_context_object(resource) + assert queryset.count() == 1 + assert queryset.first() == hitcount_contact_resource + + assert HitCount.objects.for_user(user_1).count() == 2 + + queryset = HitCount.objects.for_user(user_2) + assert queryset.count() == 1 + assert queryset.first() == hitcount_contact_project + + queryset = HitCount.objects.for_user(user_1).for_context_object(resource) + assert queryset.count() == 1 + assert queryset.first() == hitcount_contact_resource + + assert queryset.for_content_object(project).count() == 0 + assert queryset.for_content_object(contact).count() == 1