From cf0a62548acb37dd7bad2e27906824de30db4855 Mon Sep 17 00:00:00 2001 From: dwindown Date: Wed, 1 Apr 2026 18:53:59 +0700 Subject: [PATCH] Disable Tortoise model pages in admin and use SQLAlchemy-safe links --- app/admin.py | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/app/admin.py b/app/admin.py index 19e2bc5..30b0839 100644 --- a/app/admin.py +++ b/app/admin.py @@ -124,8 +124,9 @@ class EnvCredentialProvider(Provider): """ Resolve a concrete admin page path. - fastapi-admin 1.0.x does not expose a root "/" view by default; the - first usable page is a model list route: /{resource}/list. + This project uses SQLAlchemy models, while fastapi-admin's built-in + Model CRUD pages are Tortoise-oriented. Prefer custom Link resources + and known safe admin pages. """ admin_path = request.app.admin_path.rstrip("/") for resource in getattr(request.app, "resources", []): @@ -135,7 +136,15 @@ class EnvCredentialProvider(Provider): return f"{admin_path}/{model_name}/list" except TypeError: continue - return f"{admin_path}{getattr(request.app.login_provider, 'login_path', '/login')}" + for resource in getattr(request.app, "resources", []): + try: + if issubclass(resource, Link): + url = getattr(resource, "url", "") + if isinstance(url, str) and url.startswith("/"): + return url + except TypeError: + continue + return f"{admin_path}/password" @staticmethod def _login_url(request: Request) -> str: @@ -775,18 +784,24 @@ def create_admin_app() -> Any: # NOTE: fastapi-admin 1.0.4 requires provider registration via app.configure(...). # Keep provider implementation here for future integration during startup configure. - # Register model resources - admin_app.register(TryoutResource) - admin_app.register(ItemResource) - admin_app.register(UserResource) - admin_app.register(SessionResource) - admin_app.register(TryoutStatsResource) + # NOTE: + # fastapi-admin Model resources rely on Tortoise ORM query APIs. + # This codebase uses SQLAlchemy, so register only Link resources here. + # Keep Model resource classes in source for future migration work. - # Register dashboard links + # Register dashboard links (safe for SQLAlchemy-backed custom views) admin_app.register(CalibrationDashboardLink) admin_app.register(ItemStatisticsLink) admin_app.register(SessionOverviewLink) + calibration_link = CalibrationDashboardLink() + item_stats_link = ItemStatisticsLink() + session_overview_link = SessionOverviewLink() + + admin_app.get("/calibration_status", dependencies=[Depends(get_current_admin)])(calibration_link.get) + admin_app.get("/item_statistics", dependencies=[Depends(get_current_admin)])(item_stats_link.get) + admin_app.get("/session_overview", dependencies=[Depends(get_current_admin)])(session_overview_link.get) + return admin_app