SQLAdmin Documentation

repository·main·Indexed 25 days ago

https://github.com/smithyhq/sqladmin

A flexible administration interface for SQLAlchemy models, designed for integration with Starlette and FastAPI applications. Version 0.30.0 provides tools for managing database models via ModelView, custom authentication backends, flash messaging, and granular control over model visibility and permissions.

Tokens
33.8K
Snippets
88
Records
202
Agent score
80%

What's inside sqladmin

  1. Quickstart SQLAdmin with FastAPI

    main

    To integrate SQLAdmin into a FastAPI application, initialize the Admin class with your FastAPI app instance and your SQLAlchemy engine. Define a class inheriting from ModelView, specifying the model to manage, and then register it using admin.add_view(). By default, the admin interface is available at the /admin path.

    from fastapi import FastAPI
    from sqladmin import Admin, ModelView
    
    # Assuming 'engine' and 'User' model are already defined
    app = FastAPI()
    admin = Admin(app, engine)
    
    class UserAdmin(ModelView, model=User):
        column_list = [User.id, User.name]
    
    admin.add_view(UserAdmin)
  2. Quickstart SQLAdmin with Starlette

    main

    To integrate SQLAdmin into a Starlette application, initialize the Admin class with your Starlette app instance and your SQLAlchemy engine. Define a class inheriting from ModelView, specifying the model to manage, and then register it using admin.add_view(). The admin interface is available at /admin.

    from sqladmin import Admin, ModelView
    from starlette.applications import Starlette
    
    # Assuming 'engine' and 'User' model are already defined
    app = Starlette()
    admin = Admin(app, engine)
    
    class UserAdmin(ModelView, model=User):
        column_list = [User.id, User.name]
    
    admin.add_view(UserAdmin)
  3. Configure create and edit form fields with form_create_rules and form_edit_rules

    main

    You can control which fields appear in the Admin console's creation and editing forms by using form_create_rules and form_edit_rules. This is useful for hiding sensitive fields (like passwords) during edits while allowing them during initial creation.

    • form_create_rules: A list of field names to include in the 'Create' form.
    • form_edit_rules: A list of field names to include in the 'Edit' form.
    class UserAdmin(ModelView, model=User):
        # Only show name and password when creating
        form_create_rules = ["name", "hashed_password"]
        
        # Only show name when editing (hides password)
        form_edit_rules = ["name"]
  4. Access the request object by overriding ModelView methods

    main

    To access the Starlette/FastAPI request object during database operations (create, update, or delete), you can override the following methods in your ModelView class:

    • insert_model(request, data): Triggered when creating a new record.
    • update_model(request, pk, data): Triggered when updating an existing record (where pk is the primary key).
    • delete_model(request, pk): Triggered when deleting a record.

    This is useful for accessing request.user to perform audit logging or to automatically assign ownership of a record to the currently authenticated user.

    class PostAdmin(ModelView, model=Post):
        async def insert_model(self, request, data):
            data["author_id"] = request.user.id
            return await super().insert_model(request, data)
  5. Full override of default templates

    main
    If your customizations are too extensive for block-based overrides, you can completely replace a default template. Copy the existing template from SQLAdmin's templates/sqladmin into your project's templates/sqladmin directory. Do not use extends; the file in your project directory will be loaded instead of the package default.
  6. Add a new language to SQLAdmin

    main

    New languages must be added to the package source. The workflow uses Babel and the provided Makefile targets. Run these commands from the repository root:

    1. Extract strings: Refresh the .pot template and sync existing catalogs: make i18n-extract
    2. Initialize locale: Create a new catalog (e.g., for French): make i18n-init LOCALE=fr
    3. Translate: Edit the generated .po file at sqladmin/translations/fr/LC_MESSAGES/admin.po. Important: Remove the #, fuzzy line from the header after reviewing translations to ensure compilation.
    4. Compile: Convert .po files into binary .mo files: make i18n-compile

    Finally, add the new locale code to SUPPORTED_LOCALES in sqladmin/i18n.py and commit both the .po and .mo files.

    make i18n-extract
    make i18n-init LOCALE=fr
    # ... translate file ...
    make i18n-compile
  7. Configure rich text editor options

    main

    Pass configuration options to an editor field using the form_args dictionary in your ModelView, following the standard WTForms field argument pattern.

    from sqladmin.editors import CKEditor5Field
    
    class PostAdmin(ModelView, model=Post):
        form_overrides = {"content": CKEditor5Field}
        form_args = {"content": {"min_height": 300}}
  8. Create custom views with BaseView

    main

    To add custom pages like dashboards or custom forms to the SQLAdmin interface, inherit from BaseView. You can define the view's display name using name, an icon using icon (FontAwesome syntax), and define endpoints using the @expose decorator.

    By default, SQLAdmin looks for templates in a templates directory. If you use a custom directory, configure it when initializing the Admin object using templates_dir.

    from sqladmin import BaseView, expose
    
    class ReportView(BaseView):
        name = "Report Page"
        icon = "fa-solid fa-chart-line"
    
        @expose("/report", methods=["GET"])
        async def report_page(self, request):
            return await self.templates.TemplateResponse(request, "report.html")
    
    admin.add_view(ReportView)
  9. Integrate SQLAdmin with FastAPI

    main

    To use SQLAdmin in a FastAPI application, initialize the Admin class with your FastAPI app instance and your SQLAlchemy engine. Then, create a class that inherits from ModelView, specifying the SQLAlchemy model it manages, and add it to the admin instance using add_view().

    from fastapi import FastAPI
    from sqladmin import Admin, ModelView
    
    app = FastAPI()
    admin = Admin(app, engine)
    
    class UserAdmin(ModelView, model=User):
        column_list = [User.id, User.name]
    
    admin.add_view(UserAdmin)
  10. Use multiple databases with sqladmin via sessionmaker

    main

    To support multiple databases (partitioning) in sqladmin, do not pass an engine to the Admin constructor. Instead, configure a SQLAlchemy sessionmaker with specific binds for different models and pass that factory to the session_maker argument of Admin.

    This allows you to route different models (e.g., User to engine1 and Account to engine2) to different database engines within the same admin interface.

  11. Access the database in custom views

    main

    To perform database operations within a BaseView, use your existing SQLAlchemy sessionmaker (configured with AsyncSession for async drivers). You can execute queries and pass the results to your template via the context argument in self.templates.TemplateResponse.

    from sqlalchemy import select, func
    from sqlalchemy.orm import sessionmaker
    from sqladmin import BaseView, expose
    
    # Assuming Session is your configured async sessionmaker
    class ReportView(BaseView):
        name = "Report Page"
        icon = "fa-solid fa-chart-line"
    
        @expose("/report", methods=["GET"])
        async def report_page(self, request):
            async with Session(expire_on_commit=False) as session:
                stmt = select(func.count(User.id))
                result = await session.execute(stmt)
                users_count = result.scalar_one()
    
            return await self.templates.TemplateResponse(
                request,
                "report.html",
                context={"users_count": users_count},
            )
    
    admin.add_view(ReportView)
  12. Optimize relationship loading with `form_ajax_refs`

    main

    When editing a model with many related records (e.g., a One-To-Many or Many-To-Many relationship), SQLAdmin defaults to loading all related objects into an HTML select element. For large tables, this causes significant performance issues.

    To prevent loading all records at once, use form_ajax_refs to enable AJAX-based searching and loading for specific relationship fields. This allows users to search for related objects via an asynchronous call.

    class ParentAdmin(ModelView, model=Parent):
        form_ajax_refs = {
            "children": {
                "fields": ("id",),
                "order_by": "id",
            }
        }