Skip to content

Commit

Permalink
Merge pull request #90 from Pet-projects-CodePET/feature/profile
Browse files Browse the repository at this point in the history
[+] Модель профиля
  • Loading branch information
Nadya2502 authored Mar 25, 2024
2 parents fe6fc66 + 55480ac commit e529928
Show file tree
Hide file tree
Showing 23 changed files with 669 additions and 20 deletions.
Empty file.
9 changes: 9 additions & 0 deletions src/backend/api/v1/profile/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True

return obj.owner or obj.creator == request.user
69 changes: 69 additions & 0 deletions src/backend/api/v1/profile/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
from rest_framework import generics, serializers

from apps.profile.models import Profile, UserSkill, UserSpecialization
from apps.projects.models import Skill, Specialist


class ProfileSerializer(serializers.Serializer):
"""Модель сериализатора на просмотр профиля с учетом выбора видимости контактов"""

class Meta:
model = Profile
fields = "__all__"

def to_representation(self, instance):
user = self.context["request"].user
visible_status_contacts = instance.visible_status_contacts
if visible_status_contacts in [Profile.NOBODY] or (
not user.is_organizer
and visible_status_contacts in [Profile.CREATOR_ONLY]
):
self.fields.pop("phone_number")
self.fields.pop("email")
self.fields.pop("telegram")

return super().to_representation(instance)


class ProfileUpdateSerializer(serializers.ModelSerializer):
"""Сериализатор на редактирование профиля пользователя."""

user = serializers.HiddenField(default=serializers.CurrentUserDefault())

class Meta:
model = Profile
fields = "__all__"


class UserSkillSerializer(serializers.ModelSerializer):
skills = serializers.PrimaryKeyRelatedField(
queryset=Skill.objects.all(), many=True
)

class Meta:
model = UserSkill
fields = ["user", "skill"]
validators = [
serializers.UniqueTogetherValidator(
queryset=UserSkill.objects.all(),
fields=["user", "skill"],
message="Этот навык вами уже был выбран",
)
]


class UserSpecializationSerializer(serializers.ModelSerializer):
specialization = serializers.PrimaryKeyRelatedField(
queryset=Specialist.objects.all(), many=True
)

class Meta:
model = UserSpecialization
fields = ["user", "specialization"]
validators = [
serializers.UniqueTogetherValidator(
queryset=UserSpecialization.objects.all(),
fields=["user", "specialization"],
message="Этот специализация вами уже была выбрана",
)
]
12 changes: 12 additions & 0 deletions src/backend/api/v1/profile/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

from apps.profile.models import Profile


@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
"""Функция автоматического создания профиля при создании пользователя"""
if created:
Profile.objects.create(user=instance)
8 changes: 8 additions & 0 deletions src/backend/api/v1/profile/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import include, path

from api.v1.profile.views import ProfileListAPIView, ProfileView

urlpatterns = [
path("profiles/", ProfileListAPIView.as_view(), name="profile-list"),
path("profiles/<pk>", ProfileView.as_view(), name="profile"),
]
37 changes: 37 additions & 0 deletions src/backend/api/v1/profile/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from django.db.models import Q
from rest_framework import generics

from api.v1.profile.permissions import IsOwnerOrReadOnly
from api.v1.profile.serializers import (
ProfileSerializer,
ProfileUpdateSerializer,
)
from apps.profile.models import Profile
from apps.projects.models import Project


class ProfileView(generics.UpdateAPIView):
"""Представление на изменение данных в профиле"""

queryset = Profile.objects.all()
serializer_class = ProfileUpdateSerializer
permission_classes = [IsOwnerOrReadOnly]


class ProfileListAPIView(generics.ListAPIView):
"""Список профилей в зависимости от их видимости"""

serializer_class = ProfileSerializer

def get_queryset(self):
user = self.request.user
queryset = Profile.objects.all()
is_organizer = user.is_authenticated and user.is_organizer
if is_organizer:
queryset = queryset.filter(
visible_status__in=[Profile.ALL, Profile.CREATOR_ONLY]
)
else:
queryset = queryset.filter(visible_status=Profile.ALL)

return queryset
1 change: 1 addition & 0 deletions src/backend/api/v1/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
path("", include("api.v1.users.urls")),
path("", include("djoser.urls.authtoken")),
path("", include("api.v1.general.urls")),
path("", include("api.v1.profile.urls")),
path("schema/", SpectacularAPIView.as_view(), name="schema"),
path("schema/docs/", SpectacularSwaggerView.as_view(url_name="schema")),
]
11 changes: 9 additions & 2 deletions src/backend/apps/general/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MAX_LENGTH_SKILL_NAME = 100

MAX_LENGTH_SPECIALIZATION_NAME = 50
MAX_LENGTH_SPECIALIZATION_NAME = 100
MIN_LENGTH_SPECIALIZATION_NAME = 2
LENGTH_SPECIALIZATION_NAME_ERROR_TEXT = (
f"Длина поля от {MIN_LENGTH_SPECIALIZATION_NAME} до "
Expand All @@ -12,7 +12,7 @@
"и символ /"
)

MAX_LENGTH_SPECIALTY_NAME = 100
MAX_LENGTH_SPECIALTY_NAME = 50
MIN_LENGTH_SPECIALTY_NAME = 2
LENGTH_SPECIALTY_NAME_ERROR_TEXT = (
f"Длина поля от {MIN_LENGTH_SPECIALTY_NAME} до "
Expand Down Expand Up @@ -47,3 +47,10 @@
"Введите корректное имя пользователя. Оно может состоять из латинских "
"букв, цифр и символа подчеркивания."
)
LEVEL_CHOICES = (
(1, "intern"),
(2, "junior"),
(3, "middle"),
(4, "senior"),
(5, "lead"),
)
14 changes: 7 additions & 7 deletions src/backend/apps/general/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.0.1 on 2024-03-13 13:24
# Generated by Django 5.0.1 on 2024-03-24 16:00

import django.core.validators
from django.db import migrations, models
Expand Down Expand Up @@ -81,15 +81,15 @@ class Migration(migrations.Migration):
(
"specialty",
models.CharField(
max_length=100,
max_length=50,
validators=[
django.core.validators.MinLengthValidator(
limit_value=2,
message="Длина поля от 2 до 100 символов.",
message="Длина поля от 2 до 50 символов.",
),
django.core.validators.RegexValidator(
message="Специальность может содержать: кириллические и латинские символы.",
regex="(^[A-Za-zА-Яа-яЁё\\s\\/]+)\\Z",
regex="(^[A-Za-zА-Яа-яЁё]+)\\Z",
),
],
verbose_name="Специализация",
Expand All @@ -98,15 +98,15 @@ class Migration(migrations.Migration):
(
"specialization",
models.CharField(
max_length=50,
max_length=100,
validators=[
django.core.validators.MinLengthValidator(
limit_value=2,
message="Длина поля от 2 до 2 символов.",
),
django.core.validators.RegexValidator(
message="Специализация может содержать: кириллические и латинские символы.",
regex="(^[A-Za-zА-Яа-яЁё]+)\\Z",
message="Специализация может содержать: кириллические и латинские символы,пробелы и символ /",
regex="(^[A-Za-zА-Яа-яЁё\\s\\/]+)\\Z",
),
],
verbose_name="Специальность",
Expand Down
Empty file.
14 changes: 14 additions & 0 deletions src/backend/apps/profile/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
BOOL_CHOICES = [(True, "Готов"), (False, "Не готов")]
MAX_LENGTH_NAME = 30
MAX_LENGTH_COUNTRY = 255
MAX_LENGTH_CITY = 255
MAX_LENGTH_ABOUT = 750
MAX_LENGTH_URL = 256
MIN_LENGTH_NAME = 2
MIN_LENGTH_ABOUT = 50
MIN_LENGTH_PORTFOLIO = 5
VISIBLE_CHOICES = [
(1, "All"),
(2, "Only creator"),
(3, "Nobody"),
]
Loading

0 comments on commit e529928

Please sign in to comment.