Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions users/migrations/0054_alter_customuser_first_name_and_more.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Generated by Django 4.2.11 on 2025-08-20 07:55

from django.db import migrations, models
import functools
import users.validators


class Migration(migrations.Migration):

dependencies = [
("users", "0053_customuser_is_mospolytech_student_and_more"),
]

operations = [
migrations.AlterField(
model_name="customuser",
name="first_name",
field=models.CharField(
max_length=255,
validators=[
functools.partial(
users.validators.user_name_validator, *(), **{"field_name": "Имя"}
)
],
),
),
migrations.AlterField(
model_name="customuser",
name="last_name",
field=models.CharField(
max_length=255,
validators=[
functools.partial(
users.validators.user_name_validator,
*(),
**{"field_name": "Фамилия"}
)
],
),
),
migrations.AlterField(
model_name="customuser",
name="patronymic",
field=models.CharField(
blank=True,
max_length=255,
null=True,
validators=[
functools.partial(
users.validators.user_name_validator,
*(),
**{"field_name": "Отчество"}
)
],
),
),
]
29 changes: 24 additions & 5 deletions users/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from functools import partial

from django.contrib.auth.models import AbstractUser
from django.contrib.contenttypes.fields import GenericRelation
from django.core.exceptions import ValidationError
from django.core.validators import URLValidator
from django.db import models
from django.db.models import QuerySet
from django.utils import timezone
Expand Down Expand Up @@ -60,9 +63,18 @@ class CustomUser(AbstractUser):
INVESTOR = constants.INVESTOR

username = None
email = models.EmailField(unique=True)
first_name = models.CharField(max_length=255, validators=[user_name_validator])
last_name = models.CharField(max_length=255, validators=[user_name_validator])
email = models.EmailField(
unique=True,
error_messages={
"unique": "Пользователь с таким email уже существует",
},
)
first_name = models.CharField(
max_length=255, validators=[partial(user_name_validator, field_name="Имя")]
)
last_name = models.CharField(
max_length=255, validators=[partial(user_name_validator, field_name="Фамилия")]
)
password = models.CharField(max_length=255)
is_active = models.BooleanField(default=False, editable=False)
user_type = models.PositiveSmallIntegerField(
Expand All @@ -74,7 +86,10 @@ class CustomUser(AbstractUser):
editable=False,
)
patronymic = models.CharField(
max_length=255, validators=[user_name_validator], null=True, blank=True
max_length=255,
validators=[partial(user_name_validator, field_name="Отчество")],
null=True,
blank=True,
)
# TODO need to be removed in future `key_skills` -> `skills`.
key_skills = models.CharField(
Expand All @@ -87,7 +102,11 @@ class CustomUser(AbstractUser):
"core.SkillToObject",
related_query_name="users",
)
avatar = models.URLField(null=True, blank=True)
avatar = models.URLField(
null=True,
blank=True,
validators=[URLValidator(message="Введите корректный URL")],
)
birthday = models.DateField(
validators=[user_birthday_validator],
)
Expand Down
16 changes: 16 additions & 0 deletions users/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.forms.models import model_to_dict
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.validators import UniqueValidator
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from core.models import Skill, SkillToObject, Specialization, SpecializationCategory
Expand Down Expand Up @@ -692,6 +693,21 @@ class Meta:
class UserListSerializer(
serializers.ModelSerializer[CustomUser], SkillsWriteSerializerMixin
):
email = serializers.EmailField(
validators=[
UniqueValidator(
queryset=CustomUser.objects.all(),
message="Пользователь с таким email уже существует",
)
],
error_messages={"invalid": "Введите корректный email адрес"},
)
avatar = serializers.URLField(
required=False,
allow_null=True,
error_messages={"invalid": "Введите корректный url адрес"},
)

member = MemberSerializer(required=False)
is_online = serializers.SerializerMethodField()

Expand Down
27 changes: 14 additions & 13 deletions users/validators.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import phonenumbers
from django.core.exceptions import ValidationError as DjangoValidationError
from django.utils import timezone
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from django.core.exceptions import ValidationError as DjangoValidationError

import phonenumbers

from users.constants import NOT_VALID_NUMBER_MESSAGE

Expand All @@ -18,19 +17,19 @@ def user_birthday_validator(birthday):
raise ValidationError("Человек младше 12 лет")


def user_name_validator(name):
"""returns true if name is valid"""
# TODO: add check for vulgar words
def user_name_validator(value, field_name="Поле"):
"""Валидатор для имени, фамилии и отчества"""
if not value:
return

valid_name_chars = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
for letter in name:
for letter in value:
if letter.upper() not in valid_name_chars:
raise ValidationError(
"Имя содержит недопустимые символы. Могут быть только символы кириллического алфавита."
raise DjangoValidationError(
f"{field_name} содержит недопустимые символы. Могут быть только символы кириллического алфавита."
)
if len(name) < 2:
raise ValidationError("Имя слишком короткое")
return True
if len(value) < 2:
raise DjangoValidationError(f"Поле '{field_name}' слишком короткое")


def specialization_exists_validator(pk: int):
Expand All @@ -49,7 +48,9 @@ def user_experience_years_range_validator(value: int):
(2000 - `now.year`)
"""
if value not in range(2000, timezone.now().year + 1):
raise DjangoValidationError(f"Год должен быть в диапазоне 2000 - {timezone.now().year}")
raise DjangoValidationError(
f"Год должен быть в диапазоне 2000 - {timezone.now().year}"
)


def user_phone_number_validation(value: str):
Expand Down