Skip to content

Commit

Permalink
Admin panel complete
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpro2022 committed Mar 25, 2024
1 parent d7ddd0c commit 6a0700f
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 114 deletions.
12 changes: 9 additions & 3 deletions app/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
from starlette_admin.contrib.sqla import Admin
from app.core.dependencies import engine
from .views import City, CityView, Vacancy, VacancyView
from app.models import models as m
from . import views as v

admin = Admin(
engine,
"💾 База данных HRSpace",
)

admin.add_view(CityView(City))
admin.add_view(VacancyView(Vacancy))
admin.add_view(v.VacancyView(m.Vacancy))
admin.add_view(v.CategoryView(m.Category))
admin.add_view(v.CityView(m.City))
admin.add_view(v.ConditionView(m.Condition))
admin.add_view(v.RequirementsView(m.Requirement))
admin.add_view(v.ResponsibilitiesView(m.Responsibility))
admin.add_view(v.SpecializationView(m.Specialization))
37 changes: 26 additions & 11 deletions app/admin/views.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,38 @@
from starlette_admin.contrib.sqla import ModelView

from app.models.models import City, Specialization, Vacancy
from app.models import models as m


class GenericView(ModelView):
fields = ("id", "name")


class CityView(GenericView):
model = City
class CityView(ModelView):
model = m.City
name = "Города"


class SpecializationView(GenericView):
model = Specialization
class SpecializationView(ModelView):
model = m.Specialization
name = "Специальность"


class VacancyView(ModelView):
# fields = "__all__"
model = Vacancy
model = m.Vacancy
name = "Заявка"


class CategoryView(ModelView):
model = m.Category
name = "Сфера деятельности"


class ConditionView(ModelView):
model = m.Condition
name = "Условия труда"


class RequirementsView(ModelView):
model = m.Requirement
name = "Требования"


class ResponsibilitiesView(ModelView):
model = m.Responsibility
name = "Обязанности"
7 changes: 3 additions & 4 deletions app/api/endpoints/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,9 @@ async def get_data(vacancy_name_id: int, city_id: int, session: async_session):
@router.post(
"/vacancy",
status_code=201,
# response_model=schemas.VacancyOut,
# responses={**responses.get_400("Object")},
response_model=schemas.VacancyOut,
summary=SUM_VACANCY,
description=(f"{settings.ALL_USERS} {SUM_VACANCY}"),
)
async def post_vacancy(payload: schemas.VacancyIn, session: async_session):
pass
async def create_vacancy(payload: schemas.VacancyIn, session: async_session):
return await crud.create(session, models.Vacancy, **payload.model_dump())
18 changes: 8 additions & 10 deletions app/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ class Settings(BaseSettings):
# constants
URL_PREFIX: str = "/api/v1/"
DEFAULT_STR: str = "To be implemented in .env file"
# SUPER_ONLY: str = '__Только для суперюзеров:__ '
# AUTH_ONLY: str = '__Только для авторизованных пользователей:__ '
ALL_USERS: str = "__Для всех пользователей:__ "

# Application settings
Expand All @@ -21,11 +19,11 @@ class Settings(BaseSettings):
name_max_len: int = 256

# DB settings
postgres_user: str # = "postgres"
postgres_password: str # = "postgres"
db_host: str # = "db"
db_port: str # = "5432"
postgres_db: str # = "postgres"
postgres_user: str
postgres_password: str
db_host: str
db_port: str
postgres_db: str

# vacancy settings
grade_max_len: int = 6
Expand All @@ -47,8 +45,8 @@ class Settings(BaseSettings):
description_max_len: int = 512
number_of_recruiters: tuple[int, ...] = (1, 2, 3)
hr_salary_model: tuple[int, ...] = (0, 1, 2)
when_work_max_len: int = 18
what_need_max_len: int = 19
when_work_max_len: int = 20
what_need_max_len: int = 100
vacancy_when_work_options: tuple[str, ...] = (
"Срочно",
"Не очень срочно",
Expand All @@ -62,7 +60,7 @@ class Settings(BaseSettings):
)
vacancy_what_need_options: tuple[str, ...] = (
"Только резюме",
"Резюме + результаты собеседования",
"Резюме + результаты собеседования",
)
requirements_max_len: int = 2000

Expand Down
4 changes: 2 additions & 2 deletions app/data/cities.csv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name
Москва
Санкт_Петербург
Санкт-Петербург
Вологда
Казань
Владивосток
Красноярск
Воронеж
Белгород
Белгород
60 changes: 24 additions & 36 deletions app/models/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from decimal import Decimal

from sqlalchemy import ARRAY, Boolean, ForeignKey, String
from sqlalchemy import Boolean, ForeignKey, Integer, String
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.core.config import settings
Expand All @@ -18,72 +19,59 @@ def __repr__(self) -> str:


class Vacancy(GenericModel):
# __tablename__ = "vacancies"
# vacancy_name: Mapped[str] = mapped_column(String(settings.name_max_len))
specialization_id: Mapped[int] = mapped_column(ForeignKey("specialization.id"))
specialization: Mapped["Specialization"] = relationship() # "Specialization")
city_id: Mapped[int] = mapped_column(ForeignKey("city.id"))
city: Mapped["City"] = relationship() # "City")
salary_from: Mapped[Decimal]
# mapped_column(Decimal(settings.decimal_precision, settings.decimal_scale))
salary_to: Mapped[Decimal]
# mapped_column(Decimal(settings.decimal_precision, settings.decimal_scale))
hr_salary: Mapped[Decimal]
hr_salary_model: Mapped[int]
employee_to_search: Mapped[int]
number_of_recruiters: Mapped[int]
#
grade: Mapped[str] = mapped_column(String(settings.grade_max_len))
experience: Mapped[str] = mapped_column(String(settings.experience_max_len))

work_type: Mapped[list] = mapped_column(ARRAY(String))
employment: Mapped[str] = mapped_column(String(settings.employment_max_len))
registration_type: Mapped[str] = mapped_column(String(settings.reg_type_max_len))
"""responsibilities: Mapped[list["Responsibility"]] = relationship(
# "Responsibility",
# secondary="vacancy_responsibilities",
# back_populates="vacancies",
#)
when_work: Mapped[str] = mapped_column(String(settings.when_work_max_len))
what_need: Mapped[str] = mapped_column(String(settings.what_need_max_len))
#
work_types: Mapped[list] = mapped_column(ARRAY(String))
responsibilities_ids = mapped_column(ARRAY(Integer))
responsibilities_description: Mapped[str] = mapped_column(
String(settings.description_max_len)
)
requirements: Mapped[list["Requirement"]] = relationship( # "Requirement",
secondary="vacancy_requirements", back_populates="vacancies"
)
requirements_ids = mapped_column(ARRAY(Integer))
requirements_description: Mapped[str] = mapped_column(
String(settings.description_max_len)
)
conditions: Mapped[list["Condition"]] = relationship( # "Condition",
secondary="vacancy_conditions", back_populates="vacancies"
)
conditions_ids = mapped_column(ARRAY(Integer))
conditions_description: Mapped[str] = mapped_column(
String(settings.description_max_len)
)"""
hr_salary_model: Mapped[int] # = mapped_column(Integer)
hr_salary: Mapped[Decimal]
# mapped_column(Decimal(settings.decimal_precision, settings.decimal_scale))
employee_to_search: Mapped[int] # = mapped_column(Integer)
number_of_recruiters: Mapped[int] # = mapped_column(Integer)
when_work: Mapped[str] = mapped_column(String(settings.when_work_max_len))
what_need: Mapped[str] = mapped_column(String(settings.what_need_max_len))
additional_tasks: Mapped[list] = mapped_column(ARRAY(String))
)
additional_tasks = mapped_column(ARRAY(String))
special_requirements: Mapped[str] = mapped_column(
String(settings.requirements_max_len), default=""
)
show_info: Mapped[bool] = mapped_column(Boolean, default=False)

def __repr__(self) -> str:
return (
f"\nvacancy_name: {self.vacancy_name}"
f"\nspecialization: {self.specialization}"
f"\nid: {self.id}"
f"\nname: {self.name}"
f"\nspecialization_id: {self.specialization_id}"
f"\nsalary_from: {self.salary_from}"
f"\nsalary_to: {self.salary_to}"
f"\ngrade: {self.grade}"
f"\nexperience: {self.experience}"
f"\ncity: {self.city}"
f"\nwork_type: {self.work_type}"
f"\ncity_id: {self.city_id}"
f"\nwork_type: {self.work_types}"
f"\nemployment: {self.employment}"
f"\nregistration_type: {self.registration_type}"
f"\nresponsibilities: {self.responsibilities}"
f"\nresponsibilities: {self.responsibilities_ids}"
f"\nresponsibilities_description: {self.responsibilities_description}"
f"\nrequirements: {self.requirements}"
f"\nrequirements: {self.requirements_ids}"
f"\nrequirements_description: {self.requirements_description}"
f"\nconditions: {self.conditions}"
f"\nconditions: {self.conditions_ids}"
f"\nconditions_description: {self.conditions_description}"
f"\nhr_salary_model: {self.hr_salary_model}"
f"\nhr_salary: {self.hr_salary}"
Expand Down
25 changes: 6 additions & 19 deletions app/repositories/crud.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from fastapi import HTTPException, status
from sqlalchemy import insert, select
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession


Expand All @@ -21,21 +21,8 @@ async def get_or_404(session: AsyncSession, model, id: int):


async def create(session: AsyncSession, model, **kwargs):
return await session.execute(insert(model).values(**kwargs))


'''
# obj = model(**kwargs)
async def _save(self, obj: ModelType) -> ModelType:
"""Raises `BAD_REQUEST` exception if object already exists in DB. """
self.session.add(obj)
try:
await self.session.commit()
except exc.IntegrityError:
await self.session.rollback()
raise HTTPException(status.HTTP_400_BAD_REQUEST,
self.msg_already_exists)
await self.session.refresh(obj)
return obj
'''
obj = model(**kwargs)
session.add(obj)
await session.commit()
await session.refresh(obj)
return obj
22 changes: 2 additions & 20 deletions app/schemas/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,24 +143,6 @@ def validate_what_need(cls, value):
raise ValueError("Invalid what_need option")
return value

""" @field_validator("work_type")
@classmethod
def validate_work_type(cls, value_list):
for value in value_list:
if value not in settings.work_types:
raise ValueError("Invalid work_type")
return value_list

@field_validator("number_of_recruiters")
@classmethod
def validate_number_of_recruiters(cls, value):
if value not in settings.number_of_recruiters:
raise ValueError("Invalid number of recruiters")
return value
@field_validator("hr_salary_model")
@classmethod
def validate_hr_salary_model(cls, value):
if value not in settings.hr_salary_model:
raise ValueError("Invalid hr_salary_model")
return value """
class VacancyOut(Base, VacancyIn):
pass
4 changes: 0 additions & 4 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,11 @@ services:
condition: service_healthy
expose:
- 8000
#ports:
# - 81:8000
env_file:
- ../.env

frontend:
image: alexpro1972/hrspace_frontend
#expose:
# - 3000
ports:
- 81:3000

Expand Down
1 change: 0 additions & 1 deletion docker/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ server {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
# proxy_pass http://frontend:3000;
proxy_pass http://backend:8000;
}
}
4 changes: 0 additions & 4 deletions docker/server.docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,11 @@ services:
- db
expose:
- 8000
#ports:
# - 81:8000
env_file:
- ./.env

frontend:
image: "${DOCKERHUB_USERNAME}/${PROJECT_NAME}_frontend"
#expose:
# - 3000
ports:
- 81:3000

Expand Down
2 changes: 2 additions & 0 deletions env_example
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ POSTGRES_PASSWORD=postgrespw
DB_HOST=db
DB_PORT=5432
POSTGRES_DB=postgres

SERVER_HOST=localhost

0 comments on commit 6a0700f

Please sign in to comment.