Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Переделка профиля под требования фронтов #89

Merged
merged 1 commit into from
Jul 8, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""add second name into profile model

Revision ID: 0c8b90f5b8c4
Revises: b508b9e595d0
Create Date: 2024-07-06 22:43:01.338162

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = '0c8b90f5b8c4'
down_revision = 'b508b9e595d0'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.add_column(sa.Column('second_name', sa.String(length=100), nullable=True))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.drop_column('second_name')

# ### end Alembic commands ###
39 changes: 39 additions & 0 deletions alembic/versions/981474c39706_add_gender_into_profile_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
"""add gender into profile model

Revision ID: 981474c39706
Revises: b1d3664d675b
Create Date: 2024-07-06 23:53:35.733199

"""
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils


# revision identifiers, used by Alembic.
revision = '981474c39706'
down_revision = 'b1d3664d675b'
branch_labels = None
depends_on = None


GENDERS = [
('male', 'male'),
('female', 'female')
]


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.add_column(sa.Column('gender', sqlalchemy_utils.types.choice.ChoiceType(choices=GENDERS), nullable=True))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.drop_column('gender')

# ### end Alembic commands ###
32 changes: 32 additions & 0 deletions alembic/versions/b1d3664d675b_remove_age_from_profile_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""remove age from profile model

Revision ID: b1d3664d675b
Revises: b3b2fb7b2022
Create Date: 2024-07-06 23:11:54.283835

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b1d3664d675b'
down_revision = 'b3b2fb7b2022'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.drop_column('age')

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.add_column(sa.Column('age', sa.SMALLINT(), autoincrement=False, nullable=True))

# ### end Alembic commands ###
32 changes: 32 additions & 0 deletions alembic/versions/b3b2fb7b2022_add_birthday_into_profile_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
"""add birthday into profile model

Revision ID: b3b2fb7b2022
Revises: 0c8b90f5b8c4
Create Date: 2024-07-06 23:06:24.952315

"""
from alembic import op
import sqlalchemy as sa


# revision identifiers, used by Alembic.
revision = 'b3b2fb7b2022'
down_revision = '0c8b90f5b8c4'
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.add_column(sa.Column('birthday', sa.DateTime(), nullable=True))

# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('profile', schema=None) as batch_op:
batch_op.drop_column('birthday')

# ### end Alembic commands ###
2 changes: 0 additions & 2 deletions app/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@


class ProfileFilter(Filter):
age__gte: Optional[int] = Field(None)
age__lte: Optional[int] = Field(None)
first_name__ilike: Optional[str] = Field(None)
last_name__ilike: Optional[str] = Field(None)

Expand Down
4 changes: 3 additions & 1 deletion app/api_docs_responses/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
'id': 0,
'first_name': 'Имя',
'last_name': 'Фамилия',
'age': 0,
'second_name': 'Отчество',
'birthday': '1976-05-28',
'gender': 'male',
'user_id': 0,
'image': 'Ссылка на изображение'
}
Expand Down
4 changes: 3 additions & 1 deletion app/api_docs_responses/utils_docs.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@
'value': {}
}
}
PROFILE_UPDATE_VALUE = {'first_name': 'Имя', 'last_name': 'Фамилия', 'age': 20}
PROFILE_UPDATE_VALUE = {
'first_name': 'Имя', 'last_name': 'Фамилия', 'birthday': '1976-05-28'
}
USER_VALUE = {
'password': 'Пароль',
'email': '[email protected]',
Expand Down
5 changes: 5 additions & 0 deletions app/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ class Role(str, Enum):
user = 'user'
manager = 'manager'
admin = 'admin'


class Gender(str, Enum):
male = 'male'
female = 'female'
16 changes: 13 additions & 3 deletions app/models/profile.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
from __future__ import annotations

import datetime
from pathlib import Path
from random import randint
from typing import TYPE_CHECKING

from sqlalchemy import Column, ForeignKey, SmallInteger, String
from sqlalchemy import Column, DateTime, ForeignKey, String
from sqlalchemy.orm import Mapped, relationship
from sqlalchemy_utils import ChoiceType

from app.core.config import settings
from app.core.constants import Gender
from app.core.db import Base

from .achievement import achievement_profile_association
Expand All @@ -25,14 +28,21 @@ def _random_photo(path: Path):


class Profile(Base):
GENDERS = [(gender.name, gender.value) for gender in Gender]
first_name: Mapped[str] = Column(
String(length=settings.max_length_string)
)
last_name: Mapped[str] = Column(
String(length=settings.max_length_string)
)
age: Mapped[int] = Column(
SmallInteger
second_name: Mapped[str] = Column(
String(length=settings.max_length_string)
)
birthday: Mapped[datetime.date] = Column(
DateTime
)
gender: Mapped[str] = Column(
ChoiceType(GENDERS)
)
user_id: Mapped[int] = Column(
ForeignKey('user.id'), unique=True
Expand Down
44 changes: 35 additions & 9 deletions app/schemas/profile.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,54 @@
import datetime
from typing import Optional
from typing_extensions import Annotated

from pydantic import BaseModel, Field
from pydantic import (
BaseModel, Field, WithJsonSchema, field_serializer, field_validator
)
from sqlalchemy_utils import Choice

from app.core.constants import Gender


class ProfileRead(BaseModel):
id: int
first_name: Optional[str]
last_name: Optional[str]
age: Optional[int]
second_name: Optional[str]
birthday: Optional[datetime.date]
gender: Optional[
Annotated[
Choice,
WithJsonSchema({'type': 'str'})
]
]
user_id: int
image: Optional[str]

class Config:
from_attributes = True
arbitrary_types_allowed = True


class ProfileCreate(BaseModel):
first_name: Optional[str]
last_name: Optional[str]
age: Optional[int]
user_id: int
@field_serializer('gender')
def serialize_gender(self, gender: Choice, _info):
return gender.code


class ProfileUpdate(BaseModel):
first_name: Optional[str] = Field(None)
last_name: Optional[str] = Field(None)
age: Optional[int] = Field(None)
second_name: Optional[str] = Field(None)
birthday: Optional[datetime.date] = Field(None)
gender: Optional[str] = Field(None)

@field_validator('gender')
@classmethod
def check_gender(cls, v: str):
genders = [gender.value for gender in Gender]
if v not in genders:
raise ValueError(f'В поле гендер может быть только: {genders}')
return v


class ProfileCreate(ProfileUpdate):
pass
5 changes: 4 additions & 1 deletion tests/fixtures/profile.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import datetime
from typing import AsyncGenerator

import pytest_asyncio
Expand Down Expand Up @@ -29,7 +30,9 @@ async def moc_users(
Profile(
first_name=f'name_{user.username}',
last_name=f'surname_{user.username}',
age=i + 20,
second_name=f'second_name_{user.username}',
birthday=datetime.datetime.strptime('1976-05-28', '%Y-%m-%d'),
gender='male',
user_id=user.id
) for i, user in enumerate(moc_users)
]
Expand Down
4 changes: 0 additions & 4 deletions tests/test_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,6 @@ async def test_filter_profiles(
auth_superuser
):
"""Тест фильтрации профилей."""
response = await auth_superuser.get(
'/profiles/?age__gte=22&age__lte=23'
)
assert len(response.json()) == 2
response = await auth_superuser.get(
'/profiles/?first_name__ilike=3'
)
Expand Down
Loading