Skip to content

Commit 9a72534

Browse files
authored
Merge pull request #506 from PROCOLLAB-github/dev
Изменён уровень доступа к ручку UserList
2 parents 725aea8 + 2a72875 commit 9a72534

4 files changed

Lines changed: 165 additions & 63 deletions

File tree

procollab/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@
118118
MIDDLEWARE = [
119119
"django_prometheus.middleware.PrometheusBeforeMiddleware",
120120
"django.middleware.security.SecurityMiddleware",
121+
"corsheaders.middleware.CorsMiddleware",
121122
"whitenoise.middleware.WhiteNoiseMiddleware",
122123
"django.contrib.sessions.middleware.SessionMiddleware",
123-
"corsheaders.middleware.CorsMiddleware",
124124
"django.middleware.common.CommonMiddleware",
125125
"django.middleware.csrf.CsrfViewMiddleware",
126126
"django.contrib.auth.middleware.AuthenticationMiddleware",

users/serializers.py

Lines changed: 85 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ def to_representation(self, data):
4747
if isinstance(data, list):
4848
return data
4949
return [
50-
i.replace("'", "") for i in data.strip("][").split(",") if i.replace("'", "")
50+
i.replace("'", "")
51+
for i in data.strip("][").split(",")
52+
if i.replace("'", "")
5153
]
5254

5355

@@ -107,6 +109,7 @@ class Meta:
107109

108110
class UserDataConfirmationSerializer(serializers.ModelSerializer):
109111
"""Information about the User to add to the skill confirmation information."""
112+
110113
v2_speciality = SpecializationSerializer()
111114

112115
class Meta:
@@ -148,12 +151,15 @@ def to_representation(self, instance):
148151
"""Returns correct data about user in `confirmed_by`."""
149152
data = super().to_representation(instance)
150153
data.pop("skill_to_object", None)
151-
data["confirmed_by"] = UserDataConfirmationSerializer(instance.confirmed_by).data
154+
data["confirmed_by"] = UserDataConfirmationSerializer(
155+
instance.confirmed_by
156+
).data
152157
return data
153158

154159

155160
class UserApproveSkillResponse(serializers.Serializer):
156161
"""For swagger response presentation."""
162+
157163
confirmed_by = UserDataConfirmationSerializer(read_only=True)
158164

159165

@@ -173,14 +179,14 @@ class Meta:
173179

174180
def get_approves(self, obj):
175181
"""Adds information about confirm to the skill."""
176-
confirmations = (
177-
UserSkillConfirmation.objects
178-
.filter(skill_to_object=obj)
179-
.select_related('confirmed_by')
180-
)
182+
confirmations = UserSkillConfirmation.objects.filter(
183+
skill_to_object=obj
184+
).select_related("confirmed_by")
181185
return [
182186
{
183-
"confirmed_by": UserDataConfirmationSerializer(confirmation.confirmed_by).data,
187+
"confirmed_by": UserDataConfirmationSerializer(
188+
confirmation.confirmed_by
189+
).data,
184190
}
185191
for confirmation in confirmations
186192
]
@@ -300,14 +306,15 @@ def validate(self, attrs):
300306
completion_year = attrs.get("completion_year")
301307
entry_year = attrs.get("entry_year")
302308
if (entry_year and completion_year) and (entry_year > completion_year):
303-
raise ValidationError({
304-
"entry_year": constants.USER_EXPERIENCE_YEAR_VALIDATION_MESSAGE,
305-
})
309+
raise ValidationError(
310+
{
311+
"entry_year": constants.USER_EXPERIENCE_YEAR_VALIDATION_MESSAGE,
312+
}
313+
)
306314
return attrs
307315

308316

309317
class UserEducationSerializer(UserExperienceMixin, serializers.ModelSerializer):
310-
311318
class Meta:
312319
model = UserEducation
313320
fields = [
@@ -321,7 +328,6 @@ class Meta:
321328

322329

323330
class UserWorkExperienceSerializer(UserExperienceMixin, serializers.ModelSerializer):
324-
325331
class Meta:
326332
model = UserWorkExperience
327333
fields = [
@@ -334,7 +340,6 @@ class Meta:
334340

335341

336342
class UserLanguagesSerializer(serializers.ModelSerializer):
337-
338343
class Meta:
339344
model = UserLanguages
340345
fields = [
@@ -391,11 +396,9 @@ def get_projects(self, user: CustomUser):
391396
).data
392397

393398
def get_programs(self, user: CustomUser):
394-
user_program_profiles = (
395-
user.partner_program_profiles
396-
.select_related('partner_program')
397-
.filter(partner_program__draft=False)
398-
)
399+
user_program_profiles = user.partner_program_profiles.select_related(
400+
"partner_program"
401+
).filter(partner_program__draft=False)
399402
return UserProgramsSerializer(
400403
[profile.partner_program for profile in user_program_profiles],
401404
context={"request": self.context.get("request"), "user": user},
@@ -523,7 +526,10 @@ def update(self, instance, validated_data):
523526
if attr in IMMUTABLE_FIELDS + USER_TYPE_FIELDS + RELATED_FIELDS:
524527
continue
525528
if attr == "user_type":
526-
if value == instance.user_type or value not in user_types_to_attr.keys():
529+
if (
530+
value == instance.user_type
531+
or value not in user_types_to_attr.keys()
532+
):
527533
continue
528534
# we can't change user type to Member
529535
if value == CustomUser.MEMBER:
@@ -556,13 +562,17 @@ def _update_user_education(self, instance: CustomUser, data: list[dict]) -> None
556562
serializer.save(user=instance)
557563

558564
@transaction.atomic
559-
def _update_user_work_experience(self, instance: CustomUser, data: list[dict]) -> None:
565+
def _update_user_work_experience(
566+
self, instance: CustomUser, data: list[dict]
567+
) -> None:
560568
"""
561569
Update user work experience.
562570
`PUT`/ `PATCH` methods require full data about education.
563571
"""
564572
instance.work_experience.all().delete()
565-
serializer = UserWorkExperienceSerializer(data=data, many=True, context=self.context)
573+
serializer = UserWorkExperienceSerializer(
574+
data=data, many=True, context=self.context
575+
)
566576
if serializer.is_valid(raise_exception=True):
567577
serializer.save(user=instance)
568578

@@ -575,7 +585,9 @@ def _update_user_languages(self, instance: CustomUser, data: list[dict]) -> None
575585
# Only unique languages in profile.
576586
languages = [lang_data["language"] for lang_data in data]
577587
if len(languages) != len(set(languages)):
578-
raise ValidationError({"language": constants.UNIQUE_LANGUAGES_VALIDATION_MESSAGE})
588+
raise ValidationError(
589+
{"language": constants.UNIQUE_LANGUAGES_VALIDATION_MESSAGE}
590+
)
579591
# Custom validation to limit the number of languages per user to `USER_MAX_LANGUAGES_COUNT`.
580592
if len(languages) > constants.USER_MAX_LANGUAGES_COUNT:
581593
raise ValidationError(constants.COUNT_LANGUAGES_VALIDATION_MESSAGE)
@@ -591,7 +603,9 @@ def _update_user_skills(self, instance: CustomUser, data: list[int]) -> None:
591603
Required count of skills between 1 and `USER_MAX_SKILL_QUANTITY`.
592604
"""
593605
if not (1 <= len(data) <= constants.USER_MAX_SKILL_QUANTITY):
594-
raise serializers.ValidationError(constants.USER_SKILL_QUANTITY_VALIDATIONS_MESSAGE)
606+
raise serializers.ValidationError(
607+
constants.USER_SKILL_QUANTITY_VALIDATIONS_MESSAGE
608+
)
595609

596610
user_content_type = ContentType.objects.get_for_model(CustomUser)
597611

@@ -624,7 +638,9 @@ def _update_user_skills(self, instance: CustomUser, data: list[int]) -> None:
624638

625639
def _user_skills_quantity_limit_validation(self, instance: CustomUser) -> None:
626640
if instance.skills_count > constants.USER_MAX_SKILL_QUANTITY:
627-
raise serializers.ValidationError(constants.USER_SKILL_QUANTITY_VALIDATIONS_MESSAGE)
641+
raise serializers.ValidationError(
642+
constants.USER_SKILL_QUANTITY_VALIDATIONS_MESSAGE
643+
)
628644

629645
def to_representation(self, instance) -> dict[str, Any]:
630646
"""
@@ -734,6 +750,50 @@ class Meta:
734750
}
735751

736752

753+
class PublicUserSerializer(serializers.ModelSerializer):
754+
firstName = serializers.CharField(source="first_name")
755+
lastName = serializers.CharField(source="last_name")
756+
skills = serializers.SerializerMethodField()
757+
is_online = serializers.SerializerMethodField()
758+
759+
def get_skills(self, user: CustomUser) -> list:
760+
"""Возвращает список навыков без поля approves"""
761+
skills = []
762+
for sto in getattr(user, "prefetched_skills", []):
763+
skill = sto.skill
764+
skills.append(
765+
{
766+
"id": skill.id,
767+
"name": skill.name,
768+
"category": {"id": skill.category.id, "name": skill.category.name},
769+
}
770+
)
771+
return skills
772+
773+
def get_is_online(self, user: CustomUser) -> bool:
774+
"""Логика проверки онлайн-статуса"""
775+
request = self.context.get("request")
776+
if request and request.user.is_authenticated and request.user.id == user.id:
777+
return True
778+
779+
cache_key = get_user_online_cache_key(user)
780+
return cache.get(cache_key, False)
781+
782+
class Meta:
783+
model = CustomUser
784+
fields = [
785+
"id",
786+
"firstName",
787+
"lastName",
788+
"avatar",
789+
"user_type",
790+
"skills",
791+
"is_online",
792+
"birthday",
793+
"speciality",
794+
]
795+
796+
737797
class UserFeedSerializer(serializers.ModelSerializer, SkillsSerializerMixin):
738798
class Meta:
739799
model = CustomUser

users/urls.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
AchievementDetail,
66
AchievementList,
77
CurrentUser,
8+
PublicUserListView,
89
SpecialistsList,
910
UserAdditionalRolesView,
1011
UserDetail,
@@ -38,6 +39,7 @@
3839
"specialists/", SpecialistsList.as_view()
3940
), # this url actually returns mentors, experts and investors
4041
path("users/", UserList.as_view()),
42+
path('public-users/', PublicUserListView.as_view(), name='public-users'),
4143
path("users/projects/", UserProjectsList.as_view()),
4244
path("users/liked/", LikedProjectList.as_view()),
4345
path("users/roles/", UserAdditionalRolesView.as_view()),

0 commit comments

Comments
 (0)