-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What about Router per View? #771
Comments
I'm not entirely sure and I didn't think thoroughly but this approach might solve #681. |
What I learned so farFlask Admin RoutingAs I said, Flask Admin creates a dedicated blueprint for each view and they are all registered directly to the application. Consider two views: Flask Admin also registers an In Flask Admin, every view has an exposed method named So the URL-building process is like this:
Flask Admin registers Starlette Routing
Route naming: we can name our routes with a colon separator. admin_routes = [
Route(..., name="admin:index_view"),
Route(..., name="admin:user_view:index_view"),
Route(..., name="admin:rediscli1:index_view"),
Route(..., name="admin:rediscli2:index_view"),
] ConclusionEach view gets registered (mounted) to the main application. Not to an application to be mounted to the main application. Each view has a dedicated blueprint (Router or Mount instance) and each exposed function gets registered to this blueprint. Questions
In the end problem remains: View can not have a name prefix... So if the user has two custom views with the same exposed URLs, there will be conflicts... |
Checklist
Is your feature related to a problem? Please describe.
Introduction
At #767, I talked about building a RedisCLI view like in the Flask Admin.
I started building this view, but I realized that routing in the view is a bit different from the Flask Admin.
Flask Admin uses one Blueprint (
Router
equivalent in Flask) per view but SQLAdmin registers exposed methods directly to the main Starlette application instance (BaseAdmin.admin
), not a dedicatedRouter
instance of the view.So in my case, if I do this:
The
url_for
method won't work as expected.url_for("admin:rediscli:index")
will raise an error because the view is not registered as aRouter
with a name ("rediscli") and the exposed method is not registered as aRoute
with a name ("index").url_for("admin:index")
will work because exposed methods are registered as aRoute
to the main Starlette application instance.What is the problem?
In general, every view is expected to have an entry point (like a home page) and other pages. This is generally the
index
and other pages.What happens if we have multiple views with the same entry point name?
Even though
RedisCLI1
andRedisCLI2
are different views, they both have the same entry point (index
) with the same URL (/rediscli
).Thinking
RedisCLIView
comes from SQLAdmin, will cause unexpected behavior because theindex
method is already registered.Describe the solution you would like.
Solution
Every view should have its own
Router
and its exposed methods should be registered to thatRouter
.Describe alternatives you considered
I'm actively using Starlette Admin, it doesn't have a built-in
expose
method and it has a similar structure to SQLAdmin. The problem that exists here also exists there.I tried to adopt Flask Admin to work with Starlette but that's not an easy job 😆.
Additional context
Other Problems
Since the
index
,list
,details
,delete
,create
,edit
,export
, andajax_lookup
endpoints are registered directly to the main Starlette application instance, we can't override them for each view.sqladmin/sqladmin/application.py
Lines 387 to 419 in d062cfa
The user might need to override the
list
method in theModelView
but might require different logic per model. So the user must overrideAdmin
directly.The text was updated successfully, but these errors were encountered: