feat: with author sorting by shouts, followers and names
All checks were successful
Deploy on push / deploy (push) Successful in 6s

This commit is contained in:
Stepan Vladovskiy 2025-05-25 17:30:12 -03:00
parent a6b3b21894
commit b5dd690fbb
2 changed files with 85 additions and 8 deletions

1
.gitignore vendored
View File

@ -162,3 +162,4 @@ views.json
*.crt *.crt
*cache.json *cache.json
.cursor .cursor
.devcontainer/devcontainer.json

View File

@ -77,11 +77,38 @@ async def get_authors_with_stats(limit=50, offset=0, by: Optional[str] = None):
base_query = select(Author).where(Author.deleted_at.is_(None)) base_query = select(Author).where(Author.deleted_at.is_(None))
# Применяем сортировку # Применяем сортировку
# vars for statistics sorting
stats_sort_field = None
stats_sort_direction = "desc"
if by: if by:
if isinstance(by, dict): if isinstance(by, dict):
logger.debug(f"Processing dict-based sorting: {by}")
# Обработка словаря параметров сортировки # Обработка словаря параметров сортировки
from sqlalchemy import asc, desc from sqlalchemy import asc, desc, func
from orm.shout import ShoutAuthor
from orm.author import AuthorFollower
# Checking for order field in the dictionary
if "order" in by:
order_value = by["order"]
logger.debug(f"Found order field with value: {order_value}")
if order_value in ["shouts", "followers", "rating", "comments"]:
stats_sort_field = order_value
stats_sort_direction = "desc" # По умолчанию убывающая сортировка для статистики
logger.debug(f"Applying statistics-based sorting by: {stats_sort_field}")
elif order_value == "name":
# Sorting by name in ascending order
base_query = base_query.order_by(asc(Author.name))
logger.debug("Applying alphabetical sorting by name")
else:
# If order is not a stats field, treat it as a regular field
column = getattr(Author, order_value, None)
if column:
base_query = base_query.order_by(desc(column))
else:
# Regular sorting by fields
for field, direction in by.items(): for field, direction in by.items():
column = getattr(Author, field, None) column = getattr(Author, field, None)
if column: if column:
@ -99,6 +126,55 @@ async def get_authors_with_stats(limit=50, offset=0, by: Optional[str] = None):
else: else:
base_query = base_query.order_by(desc(Author.created_at)) base_query = base_query.order_by(desc(Author.created_at))
# If sorting by statistics, modify the query
if stats_sort_field == "shouts":
# Sorting by the number of shouts
from sqlalchemy import func, and_
from orm.shout import Shout, ShoutAuthor
subquery = (
select(
ShoutAuthor.author,
func.count(func.distinct(Shout.id)).label("shouts_count")
)
.select_from(ShoutAuthor)
.join(Shout, ShoutAuthor.shout == Shout.id)
.where(
and_(
Shout.deleted_at.is_(None),
Shout.published_at.is_not(None)
)
)
.group_by(ShoutAuthor.author)
.subquery()
)
base_query = (
base_query
.outerjoin(subquery, Author.id == subquery.c.author)
.order_by(desc(func.coalesce(subquery.c.shouts_count, 0)))
)
elif stats_sort_field == "followers":
# Sorting by the number of followers
from sqlalchemy import func
from orm.author import AuthorFollower
subquery = (
select(
AuthorFollower.author,
func.count(func.distinct(AuthorFollower.follower)).label("followers_count")
)
.select_from(AuthorFollower)
.group_by(AuthorFollower.author)
.subquery()
)
base_query = (
base_query
.outerjoin(subquery, Author.id == subquery.c.author)
.order_by(desc(func.coalesce(subquery.c.followers_count, 0)))
)
# Применяем лимит и смещение # Применяем лимит и смещение
base_query = base_query.limit(limit).offset(offset) base_query = base_query.limit(limit).offset(offset)