Skip to content

Commit 2c202c4

Browse files
authored
Merge pull request #150 from PROCOLLAB-github/feature/better-views
Better views for projects
2 parents dd26e45 + 41754f6 commit 2c202c4

4 files changed

Lines changed: 41 additions & 10 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Generated by Django 4.1.3 on 2023-06-20 20:46
2+
3+
from django.db import migrations
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
("projects", "0016_alter_projectnews_files"),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name="project",
15+
name="views_count",
16+
),
17+
]

projects/models.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,6 @@ class Project(models.Model):
6666

6767
objects = ProjectManager()
6868

69-
views_count = models.PositiveIntegerField(default=0)
70-
71-
def increment_views_count(self):
72-
self.views_count += 1
73-
self.save()
74-
7569
def get_short_description(self) -> Optional[str]:
7670
return self.description[:90] if self.description else None
7771

projects/serializers.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from django.contrib.auth import get_user_model
2+
from django.contrib.contenttypes.models import ContentType
23
from rest_framework import serializers
34

45
from core.fields import CustomListField
6+
from core.models import View
57
from core.services import get_views_count, get_likes_count, is_fan
68
from industries.models import Industry
79
from projects.models import Project, Achievement, Collaborator, ProjectNews
@@ -71,6 +73,7 @@ class ProjectDetailSerializer(serializers.ModelSerializer):
7173
short_description = serializers.SerializerMethodField()
7274
industry_id = serializers.IntegerField(required=False)
7375
likes_count = serializers.SerializerMethodField(method_name="count_likes")
76+
views_count = serializers.SerializerMethodField(method_name="count_views")
7477
links = serializers.SerializerMethodField()
7578

7679
@classmethod
@@ -88,6 +91,13 @@ def get_short_description(cls, project):
8891
def count_likes(self, project):
8992
return LikesOnProject.objects.filter(project=project, is_liked=True).count()
9093

94+
def count_views(self, project):
95+
# FIXME
96+
# TODO: add caching here at least every 5 minutes, otherwise will be heavy load
97+
return View.objects.filter(
98+
content_type=ContentType.objects.get_for_model(Project), object_id=project.pk
99+
).count()
100+
91101
def update(self, instance, validated_data):
92102
instance = super().update(instance, validated_data)
93103
instance.save()
@@ -132,6 +142,14 @@ class ProjectListSerializer(serializers.ModelSerializer):
132142
method_name="get_collaborator_count"
133143
)
134144
vacancies = ProjectVacancyListSerializer(many=True, read_only=True)
145+
views_count = serializers.SerializerMethodField(method_name="count_views")
146+
147+
def count_views(self, project):
148+
# FIXME
149+
# TODO: add caching here at least every 5 minutes, otherwise will be heavy load
150+
return View.objects.filter(
151+
content_type=ContentType.objects.get_for_model(Project), object_id=project.pk
152+
).count()
135153

136154
short_description = serializers.SerializerMethodField()
137155

@@ -172,9 +190,7 @@ class Meta:
172190
"views_count",
173191
]
174192

175-
read_only_fields = [
176-
"leader",
177-
]
193+
read_only_fields = ["leader", "views_count"]
178194

179195
def is_valid(self, *, raise_exception=False):
180196
return super().is_valid(raise_exception=raise_exception)

projects/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from rest_framework.response import Response
77
from rest_framework.views import APIView
88

9+
from core.models import View
910
from core.permissions import IsStaffOrReadOnly
1011
from core.serializers import SetLikedSerializer
1112
from core.services import add_view, set_like
@@ -92,7 +93,10 @@ class ProjectDetail(generics.RetrieveUpdateDestroyAPIView):
9293

9394
def retrieve(self, request, *args, **kwargs):
9495
instance = self.get_object()
95-
instance.increment_views_count()
96+
# create (or not, if it exists) a view object for project
97+
View.objects.get_or_create(
98+
user=request.user, content_type=Project, content_object=instance
99+
)
96100
serializer = self.get_serializer(instance)
97101
return Response(serializer.data)
98102

0 commit comments

Comments
 (0)