Skip to content

Commit

Permalink
Add sort_order option
Browse files Browse the repository at this point in the history
  • Loading branch information
DaymasS committed Nov 18, 2024
1 parent 67e8b80 commit 64e807a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 4 deletions.
15 changes: 14 additions & 1 deletion rating_api/models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

from sqlalchemy import UUID, Boolean, DateTime
from sqlalchemy import Enum as DbEnum
from sqlalchemy import ForeignKey, Integer, String, and_, func, or_, true
from sqlalchemy import ForeignKey, Integer, String, UnaryExpression, and_, func, nulls_last, or_, true
from sqlalchemy.ext.hybrid import hybrid_method, hybrid_property
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.orm.attributes import InstrumentedAttribute

from rating_api.settings import get_settings

Expand Down Expand Up @@ -60,6 +61,18 @@ def search_by_subject(self, query: str) -> bool:
response = and_(Comment.review_status == ReviewStatus.APPROVED, func.lower(Comment.subject).contains(query))
return response

@hybrid_method
def order_by_mark(self, query: str, asc_order: bool) -> UnaryExpression[float]:
return (
nulls_last(func.avg(getattr(Comment, query)))
if asc_order
else nulls_last(func.avg(getattr(Comment, query)).desc())
)

@hybrid_method
def order_by_name(self, query: str, asc_order: bool) -> UnaryExpression[str] | InstrumentedAttribute[str]:
return getattr(Lecturer, query) if asc_order else getattr(Lecturer, query).desc()


class Comment(BaseDbModel):
uuid: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4)
Expand Down
11 changes: 8 additions & 3 deletions rating_api/routes/lecturer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from auth_lib.fastapi import UnionAuth
from fastapi import APIRouter, Depends, Query
from fastapi_sqlalchemy import db
from sqlalchemy import and_, func, nulls_last
from sqlalchemy import and_

from rating_api.exceptions import AlreadyExists, ObjectNotFound
from rating_api.models import Comment, Lecturer, LecturerUserComment, ReviewStatus
Expand Down Expand Up @@ -80,6 +80,7 @@ async def get_lecturers(
),
subject: str = Query(''),
name: str = Query(''),
asc_order: bool = False,
) -> LecturerGetAll:
"""
`limit` - максимальное количество возвращаемых преподавателей
Expand All @@ -100,6 +101,10 @@ async def get_lecturers(
`name`
Поле для ФИО. Если передано `name` - возвращает всех преподователей, для которых нашлись совпадения с переданной строкой
`asc_order`
Если передано true, сортировать в порядке возрастания
Иначе - в порядке убывания
"""
lecturers_query = (
Lecturer.query(session=db.session)
Expand All @@ -108,9 +113,9 @@ async def get_lecturers(
.filter(Lecturer.search_by_subject(subject))
.filter(Lecturer.search_by_name(name))
.order_by(
nulls_last(func.avg(getattr(Comment, order_by)).desc())
Lecturer.order_by_mark(order_by, asc_order)
if "mark" in order_by
else getattr(Lecturer, order_by)
else Lecturer.order_by_name(order_by, asc_order)
)
)

Expand Down

0 comments on commit 64e807a

Please sign in to comment.