draft-resolvers
All checks were successful
Deploy on push / deploy (push) Successful in 46s

This commit is contained in:
Untone 2025-04-26 11:45:16 +03:00
parent 6b2ac09f74
commit a310d59432
2 changed files with 92 additions and 4 deletions

View File

@ -19,11 +19,10 @@ from orm.topic import Topic
from services.auth import login_required from services.auth import login_required
from services.db import local_session from services.db import local_session
from services.notify import notify_shout, notify_draft from services.notify import notify_shout, notify_draft
from services.schema import mutation, query from services.schema import mutation, query, type_draft
from services.search import search_service from services.search import search_service
from utils.logger import root_logger as logger from utils.logger import root_logger as logger
def create_shout_from_draft(session, draft, author_id): def create_shout_from_draft(session, draft, author_id):
# Создаем новую публикацию # Создаем новую публикацию
shout = Shout( shout = Shout(
@ -49,6 +48,15 @@ def create_shout_from_draft(session, draft, author_id):
@query.field("load_drafts") @query.field("load_drafts")
@login_required @login_required
async def load_drafts(_, info): async def load_drafts(_, info):
"""
Загружает все черновики, доступные текущему пользователю.
Предварительно загружает связанные объекты (topics, authors), чтобы избежать
ошибок с отсоединенными объектами при сериализации.
Returns:
dict: Список черновиков или сообщение об ошибке
"""
user_id = info.context.get("user_id") user_id = info.context.get("user_id")
author_dict = info.context.get("author", {}) author_dict = info.context.get("author", {})
author_id = author_dict.get("id") author_id = author_dict.get("id")
@ -59,9 +67,14 @@ async def load_drafts(_, info):
with local_session() as session: with local_session() as session:
drafts = ( drafts = (
session.query(Draft) session.query(Draft)
.options(
joinedload(Draft.topics),
joinedload(Draft.authors)
)
.filter(or_(Draft.authors.any(Author.id == author_id), Draft.created_by == author_id)) .filter(or_(Draft.authors.any(Author.id == author_id), Draft.created_by == author_id))
.all() .all()
) )
return {"drafts": drafts} return {"drafts": drafts}
@ -515,3 +528,77 @@ async def unpublish_shout(_, info, shout_id: int):
return {"error": "Failed to unpublish shout"} return {"error": "Failed to unpublish shout"}
return {"shout": shout} return {"shout": shout}
# Добавляем резолверы для полей типа Draft
@type_draft.field("authors")
def resolve_draft_authors(draft, info):
"""
Резолвер для поля authors типа Draft.
Безопасно загружает связанные объекты authors для объекта Draft,
используя новую сессию для предотвращения ошибок с отсоединенными объектами.
Args:
draft: Объект Draft
info: Контекст GraphQL запроса
Returns:
list: Список авторов или пустой список в случае ошибки
"""
try:
# Пробуем использовать уже загруженные авторы, если есть
if draft.authors and not isinstance(draft.authors, property):
return draft.authors
# Загружаем с новой сессией
with local_session() as session:
loaded_draft = (
session.query(Draft)
.options(joinedload(Draft.authors))
.filter(Draft.id == draft.id)
.first()
)
return loaded_draft.authors if loaded_draft else []
except Exception as e:
logger.error(f"Error resolving draft authors: {e}")
# Возвращаем пустой список в случае ошибки
return []
@type_draft.field("topics")
def resolve_draft_topics(draft, info):
"""
Резолвер для поля topics типа Draft.
Безопасно загружает связанные объекты topics для объекта Draft,
используя новую сессию для предотвращения ошибок с отсоединенными объектами.
Args:
draft: Объект Draft
info: Контекст GraphQL запроса
Returns:
list: Список тем или пустой список в случае ошибки
"""
try:
# Пробуем использовать уже загруженные темы, если есть
if draft.topics and not isinstance(draft.topics, property):
return draft.topics
# Загружаем с новой сессией
with local_session() as session:
loaded_draft = (
session.query(Draft)
.options(joinedload(Draft.topics))
.filter(Draft.id == draft.id)
.first()
)
return loaded_draft.topics if loaded_draft else []
except Exception as e:
logger.error(f"Error resolving draft topics: {e}")
# Возвращаем пустой список в случае ошибки
return []

View File

@ -1,14 +1,15 @@
from asyncio.log import logger from asyncio.log import logger
import httpx import httpx
from ariadne import MutationType, QueryType from ariadne import MutationType, ObjectType, QueryType
from services.db import create_table_if_not_exists, local_session from services.db import create_table_if_not_exists, local_session
from settings import AUTH_URL from settings import AUTH_URL
query = QueryType() query = QueryType()
mutation = MutationType() mutation = MutationType()
resolvers = [query, mutation] type_draft = ObjectType("Draft")
resolvers = [query, mutation, type_draft]
async def request_graphql_data(gql, url=AUTH_URL, headers=None): async def request_graphql_data(gql, url=AUTH_URL, headers=None):