Skip to content

Commit e28ced1

Browse files
committed
1. added /projects/count/
2. /projects/ now only shows not drafted projects
1 parent 354655c commit e28ced1

3 files changed

Lines changed: 49 additions & 29 deletions

File tree

projects/managers.py

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,41 +7,48 @@
77

88
class ProjectManager(Manager):
99
def get_projects_for_list_view(self):
10-
return self.get_queryset().prefetch_related(
11-
Prefetch(
12-
"industry",
13-
queryset=Industry.objects.only("name").all(),
14-
),
15-
Prefetch(
16-
"leader",
17-
queryset=CustomUser.objects.only("id").all(),
18-
),
19-
# Prefetch(
20-
# "collaborator_set",
21-
# queryset=Collaborator.objects.filter(
22-
# id__in=Subquery(
23-
# Collaborator.objects
24-
# .filter(project_id=OuterRef('project_id')).values_list('id', flat=True)[:4]
25-
# )
26-
# ),
27-
# to_attr='collaborators'
28-
# ),
29-
# Yes, this fetches the entire collaborator_set even though we only need 4 and the total count.
30-
# No, You can't do it any other way than this.
31-
# Above is a hack that can fetch max 4 vacancies, but if you use it the count will always be <=4.
32-
# To get the count right using the thing above you either have to make another godawful hack,
33-
# Or override the default QuerySet to always ask the DB only count after all the filters.
34-
# (ticket referring to the reason why you can't
35-
# prefetch N items easily https://code.djangoproject.com/ticket/26780)
36-
# (seems like in django 4.2.0 it'll be fixed but at the time of writing the latest version is 4.1.3
37-
Prefetch("collaborator_set"),
10+
return (
11+
self.get_queryset()
12+
.filter(draft=False)
13+
.prefetch_related(
14+
Prefetch(
15+
"industry",
16+
queryset=Industry.objects.only("name").all(),
17+
),
18+
Prefetch(
19+
"leader",
20+
queryset=CustomUser.objects.only("id").all(),
21+
),
22+
# Prefetch(
23+
# "collaborator_set",
24+
# queryset=Collaborator.objects.filter(
25+
# id__in=Subquery(
26+
# Collaborator.objects
27+
# .filter(project_id=OuterRef('project_id')).values_list('id', flat=True)[:4]
28+
# )
29+
# ),
30+
# to_attr='collaborators'
31+
# ),
32+
# Yes, this fetches the entire collaborator_set even though we only need 4 and the total count.
33+
# No, You can't do it any other way than this.
34+
# Above is a hack that can fetch max 4 vacancies, but if you use it the count will always be <=4.
35+
# To get the count right using the thing above you either have to make another godawful hack,
36+
# Or override the default QuerySet to always ask the DB only count after all the filters.
37+
# (ticket referring to the reason why you can't
38+
# prefetch N items easily https://code.djangoproject.com/ticket/26780)
39+
# (seems like in django 4.2.0 it'll be fixed but at the time of writing the latest version is 4.1.3
40+
Prefetch("collaborator_set"),
41+
)
3842
)
3943

4044
def get_projects_for_detail_view(self):
4145
return (
4246
self.get_queryset().prefetch_related("achievements", "collaborator_set").all()
4347
)
4448

49+
def get_projects_for_count_view(self):
50+
return self.get_queryset().filter(draft=False).only("id")
51+
4552
def check_if_owns_any_projects(self, user) -> bool:
4653
# I don't think this should work but the function has no usages, so I'll let it be
4754
return user.leader_projects.exists()

projects/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
AchievementList,
99
AchievementDetail,
1010
ProjectCollaborators,
11+
ProjectCountView,
1112
)
1213

1314
app_name = "projects"
@@ -16,6 +17,7 @@
1617
path("", ProjectList.as_view()),
1718
path("<int:pk>/collaborators", ProjectCollaborators.as_view()),
1819
path("<int:pk>/", ProjectDetail.as_view()),
20+
path("count/", ProjectCountView.as_view()),
1921
path("steps/", ProjectSteps.as_view()),
2022
path("achievements/", AchievementList.as_view()),
2123
path("achievements/<int:pk>/", AchievementDetail.as_view()),

projects/views.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from django_filters import rest_framework as filters
2-
from rest_framework import generics, permissions
2+
from rest_framework import generics, permissions, status
33
from rest_framework.response import Response
44
from rest_framework.views import APIView
55

@@ -73,6 +73,17 @@ class ProjectDetail(generics.RetrieveUpdateDestroyAPIView):
7373
permission_classes = [IsProjectLeaderOrReadOnly]
7474

7575

76+
class ProjectCountView(generics.GenericAPIView):
77+
queryset = Project.objects.get_projects_for_count_view()
78+
serializer_class = ProjectListSerializer
79+
# TODO: using this permission could result in a user not having verified email
80+
# creating a project; probably should make IsUserVerifiedOrReadOnly
81+
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
82+
83+
def get(self, request):
84+
return Response({"count": self.get_queryset().count()}, status=status.HTTP_200_OK)
85+
86+
7687
class ProjectCollaborators(generics.GenericAPIView):
7788
"""
7889
Project collaborator retrieve/add/delete view

0 commit comments

Comments
 (0)