Skip to content

Implementation multiple admin panels#1027

Open
MaximDementyev wants to merge 4 commits intosmithyhq:mainfrom
MaximDementyev:Feature-multiple-admin-panels
Open

Implementation multiple admin panels#1027
MaximDementyev wants to merge 4 commits intosmithyhq:mainfrom
MaximDementyev:Feature-multiple-admin-panels

Conversation

@MaximDementyev
Copy link
Copy Markdown
Contributor

Problem

It is not possible to add multiple administration panels within the same application

  1. SqlAdmin connects to the FastApi with a fixed name Since query routing is calculated by name, no matter how many Admin applications we create, all links will lead to the first application created. Creating an additional name parameter is not enough, it is necessary to rewrite all url calculations, request.url_for("admin:list") is used everywhere.
  2. The ModelView class uses the session_maker variable, which is a class variable. Therefore, when adding a second application, SqlAdmin session_maker will be overwritten. It turns out that no matter how many SqlAdmin applications we add, they will all work with the database added last.
    fix Multiple Admin Panels for the same fastapi App #919

Solution

  1. In sqladmin.helpers two methods have been created:
    local_url_for - Generate a URL for the specified route, taking router hierarchy into account.
    get_current_router_name - Find the router name in the hierarchy that corresponds to the target router. Traverses the routes of the start router and its nested applications (of type Mount) to find a match with the target router.
    The entire project has updated the use of request.url_for to local_url_for.
  2. session_maker is now an attribute of the class object

This made it possible to run multiple sqladmins within the same application, and also remove the restriction that SqlAdmin can only be connected to the FastApi root application.

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import declarative_base
from fastapi import FastAPI
from sqladmin import Admin, ModelView
from sqladmin import action

Base = declarative_base()
engine1 = create_engine("sqlite:///example1.db",connect_args={"check_same_thread": False})
engine2 = create_engine("sqlite:///example2.db",connect_args={"check_same_thread": False})
engine3 = create_engine("sqlite:///example3.db",connect_args={"check_same_thread": False})

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True)
    name = Column(String)

class UserAdmin(ModelView, model=User):
    column_list = [User.id, User.name]

Base.metadata.create_all(engine1)
Base.metadata.create_all(engine2)
Base.metadata.create_all(engine3)

app = FastAPI()
admin1 = Admin(app=app, engine=engine1, base_url='/admin/base1', mount_name='base1')
admin1.add_view(UserAdmin)

admin2 = Admin(app=app, engine=engine2, base_url='/admin/base2', mount_name='base2')
admin2.add_view(UserAdmin)

app3 = FastAPI()
app.mount('/api', app3, 'api')
admin3 = Admin(app=app3, engine=engine3, base_url='/admin/base3', mount_name='base3')
admin3.add_view(UserAdmin)

In the example, three administration panels are connected that are connected to different databases
admin1 is accessible via the path /admin/base1
admin2 is accessible via the path /admin/base2
admin3 is accessible via the path /api/admin/base3

If this solution is suitable, I will update the documentation and add tests for new functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Multiple Admin Panels for the same fastapi App

1 participant