upd: Добавил роут summary с выводом вмего меню со вложением

develop
Сергей Ванюшкин 2024-02-09 02:57:34 +03:00
parent 3120910552
commit ebe75b6dc3
8 changed files with 1304 additions and 1 deletions

BIN
admin/Menu.xlsx Normal file

Binary file not shown.

View File

@ -5,6 +5,7 @@ from fastapi import FastAPI
from fastfood.routers.dish import router as dish_router from fastfood.routers.dish import router as dish_router
from fastfood.routers.menu import router as menu_router from fastfood.routers.menu import router as menu_router
from fastfood.routers.submenu import router as submenu_router from fastfood.routers.submenu import router as submenu_router
from fastfood.routers.summary import router as summary_router
def create_app() -> FastAPI: def create_app() -> FastAPI:
@ -15,6 +16,7 @@ def create_app() -> FastAPI:
app.include_router(menu_router) app.include_router(menu_router)
app.include_router(submenu_router) app.include_router(submenu_router)
app.include_router(dish_router) app.include_router(dish_router)
app.include_router(summary_router)
def custom_openapi(): def custom_openapi():
with open('openapi.json') as openapi: with open('openapi.json') as openapi:

View File

@ -63,3 +63,4 @@ class RedisRepository:
async def invalidate(self, key: str, bg_task: BackgroundTasks) -> None: async def invalidate(self, key: str, bg_task: BackgroundTasks) -> None:
await self.clear_cache(f'{key}*', bg_task) await self.clear_cache(f'{key}*', bg_task)
await self.clear_cache(f'{get_key("menus")}*', bg_task) await self.clear_cache(f'{get_key("menus")}*', bg_task)
await self.clear_cache('summary', bg_task)

View File

@ -0,0 +1,19 @@
from fastapi import Depends
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from fastfood.dbase import get_async_session
from fastfood.models import Menu, SubMenu
class SummaryRepository:
def __init__(self, session: AsyncSession = Depends(get_async_session)) -> None:
self.db = session
async def get_data(self):
query = select(Menu).options(
selectinload(Menu.submenus).selectinload(SubMenu.dishes)
)
data = await self.db.execute(query)
return [x for x in data.scalars().all()]

View File

@ -0,0 +1,17 @@
from fastapi import APIRouter, BackgroundTasks, Depends
from fastfood.schemas import MenuSummary
from fastfood.service.summary import SummaryService
router = APIRouter(
prefix='/api/v1/summary',
tags=['summary'],
)
@router.get('/', response_model=list[MenuSummary])
async def get_summary(
sum: SummaryService = Depends(),
background_tasks: BackgroundTasks = BackgroundTasks(),
) -> list[MenuSummary]:
return await sum.read_data()

View File

@ -34,3 +34,11 @@ class Dish(DishBase, Menu):
class Dish_db(MenuBase): class Dish_db(MenuBase):
price: float price: float
class SubMenuSummary(Menu):
dishes: list[Dish_db]
class MenuSummary(Menu):
submenus: list[SubMenuSummary]

View File

@ -0,0 +1,54 @@
import redis.asyncio as redis # type: ignore
from fastapi import BackgroundTasks, Depends
from fastfood.dbase import get_async_redis_client
from fastfood.repository.redis import RedisRepository, get_key
from fastfood.repository.summary import SummaryRepository
from fastfood.schemas import DishBase, MenuSummary, SubMenuSummary
class SummaryService:
def __init__(
self,
sum_repo: SummaryRepository = Depends(),
redis_client: redis.Redis = Depends(get_async_redis_client),
background_tasks: BackgroundTasks = None,
) -> None:
self.sum_repo = sum_repo
self.cache = RedisRepository(redis_client)
self.key = get_key
self.bg_tasks = background_tasks
async def read_data(self):
def dump_to_schema(schema, obj):
obj = obj.__dict__
obj = {k: v for k, v in obj.items() if not k.startswith('_')}
if 'price' in obj.keys():
obj['price'] = str(obj['price'])
return schema(**obj)
cached_data = await self.cache.get(self.key('summary'))
if cached_data is not None:
return cached_data
result = []
data = await self.sum_repo.get_data()
for menu in data:
menus_res = dump_to_schema(MenuSummary, menu)
menus_res.submenus = []
for sub in menu.submenus:
sub_res = dump_to_schema(SubMenuSummary, sub)
sub_res.dishes = []
for dish in sub.dishes:
dish_res = dump_to_schema(DishBase, dish)
sub_res.dishes.append(dish_res)
menus_res.submenus.append(sub_res)
result.append(menus_res)
await self.cache.set(self.key('summary'), data, self.bg_tasks)
return result

File diff suppressed because one or more lines are too long