Skip to content

Commit 83fa88d

Browse files
committed
Finished simple stupid user recommendation
1 parent 1f5ed51 commit 83fa88d

6 files changed

Lines changed: 61 additions & 3 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
(3, "Первые продажи"),
66
(4, "Масштабирование"),
77
)
8+
9+
RECOMMENDATIONS_COUNT = 5

projects/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from django.db import models
55
from django.db.models import UniqueConstraint
66
from industries.models import Industry
7-
from projects.helpers import VERBOSE_STEPS
7+
from projects.constants import VERBOSE_STEPS
88
from projects.managers import AchievementManager, ProjectManager
99
from users.models import CustomUser
1010

projects/permissions.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,22 @@ def has_object_permission(self, request, view, obj):
1717
or obj.collaborator_set.filter(user=request.user).exists()
1818
or obj.invite_set.filter(user=request.user).exists()
1919
):
20+
return True
21+
return False
22+
23+
24+
class IsProjectLeader(BasePermission):
25+
"""
26+
Allows access to get only to project leader.
27+
"""
2028

29+
def has_permission(self, request, view) -> bool:
30+
if request.user and request.user.id:
31+
return True
32+
return False
33+
34+
def has_object_permission(self, request, view, obj):
35+
if obj.leader == request.user:
2136
return True
2237
return False
2338

@@ -44,6 +59,5 @@ def has_object_permission(self, request, view, obj):
4459
or obj.collaborator_set.filter(user=request.user).exists()
4560
or obj.invite_set.filter(user=request.user).exists()
4661
):
47-
4862
return True
4963
return False

projects/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
ProjectCollaborators,
1010
ProjectCountView,
1111
ProjectVacancyResponses,
12+
ProjectRecommendedUsers,
1213
)
1314

1415
app_name = "projects"
@@ -17,6 +18,7 @@
1718
path("", ProjectList.as_view()),
1819
path("<int:pk>/collaborators/", ProjectCollaborators.as_view()),
1920
path("<int:pk>/", ProjectDetail.as_view()),
21+
path("<int:pk>/recommended_users", ProjectRecommendedUsers.as_view()),
2022
path("count/", ProjectCountView.as_view()),
2123
path("steps/", ProjectSteps.as_view()),
2224
path("achievements/", AchievementList.as_view()),

projects/views.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
from random import sample
2+
3+
from django.contrib.auth import get_user_model
14
from django.db.models import Q
25
from django_filters import rest_framework as filters
36
from rest_framework import generics, permissions, status
@@ -7,11 +10,12 @@
710

811
from core.permissions import IsStaffOrReadOnly
912
from projects.filters import ProjectFilter
10-
from projects.helpers import VERBOSE_STEPS
13+
from projects.constants import VERBOSE_STEPS, RECOMMENDATIONS_COUNT
1114
from projects.models import Project, Achievement
1215
from projects.permissions import (
1316
IsProjectLeaderOrReadOnlyForNonDrafts,
1417
HasInvolvementInProjectOrReadOnly,
18+
IsProjectLeader,
1519
)
1620
from projects.serializers import (
1721
ProjectDetailSerializer,
@@ -20,9 +24,12 @@
2024
AchievementDetailSerializer,
2125
ProjectCollaboratorSerializer,
2226
)
27+
from users.serializers import UserListSerializer
2328
from vacancy.models import VacancyResponse
2429
from vacancy.serializers import VacancyResponseListSerializer
2530

31+
User = get_user_model()
32+
2633

2734
class ProjectList(generics.ListCreateAPIView):
2835
queryset = Project.objects.get_projects_for_list_view()
@@ -98,6 +105,34 @@ def put(self, request, pk, **kwargs):
98105
return super(ProjectDetail, self).put(request, pk)
99106

100107

108+
class ProjectRecommendedUsers(generics.RetrieveAPIView):
109+
queryset = Project.objects.all()
110+
permission_classes = [IsProjectLeader]
111+
serializer_class = UserListSerializer
112+
113+
def get(self, request, pk, **kwargs):
114+
project = self.get_object()
115+
# fixme: store key_skills and required_skills more convenient, not just as a string'
116+
117+
all_needed_skills = set()
118+
for vacancy in project.vacancies.all():
119+
all_needed_skills.update(set(vacancy.required_skills.lower().split(",")))
120+
121+
recommended_users = []
122+
for user in User.objects.get_members():
123+
if user == request.user or not user.key_skills:
124+
continue
125+
skills = set(user.key_skills.lower().split(","))
126+
if skills.intersection(all_needed_skills):
127+
recommended_users.append(user)
128+
sampled_recommended_users = sample(
129+
recommended_users, min(RECOMMENDATIONS_COUNT, len(recommended_users))
130+
)
131+
132+
serializer = self.get_serializer(sampled_recommended_users, many=True)
133+
return Response(status=status.HTTP_200_OK, data=serializer.data)
134+
135+
101136
class ProjectCountView(generics.GenericAPIView):
102137
queryset = Project.objects.get_projects_for_count_view()
103138
serializer_class = ProjectListSerializer

users/managers.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from django.contrib.auth.models import UserManager
33
from django.db.models import Manager
44

5+
from users.helpers import MEMBER
6+
57

68
class CustomUserManager(UserManager):
79
def create_user(self, email, password=None, **extra_fields):
@@ -39,6 +41,9 @@ def get_users_for_detail_view(self):
3941
.all()
4042
)
4143

44+
def get_members(self):
45+
return self.get_queryset().filter(user_type=MEMBER)
46+
4247
def _create_user(self, email, password, **extra_fields):
4348
email = self.normalize_email(email)
4449
user = self.model(email=email, **extra_fields)

0 commit comments

Comments
 (0)