FastAdmin

repository·main·Indexed 43 days ago

https://github.com/vsdudakov/fastadmin

A production-ready CRUD admin dashboard for FastAPI, Flask, and Django inspired by Django Admin. Version 0.10.0 supports multiple Python ORMs including SQLAlchemy 2.x, Tortoise ORM, Pony ORM, Yara ORM, and Django ORM. It provides a familiar interface with features such as relationship management, bulk actions, file uploads, and customizable display fields.

Tokens
40.7K
Snippets
116
Records
147
Agent score
55%

What's inside FastAdmin

  1. FastAdmin Features demonstrated in the FastAPI + Yara ORM example

    main

    The FastAPI + Yara ORM example serves as a demonstration of the following FastAdmin capabilities:

    • Relationship Management: Handling foreign keys, one-to-one, and many-to-many relations.
    • UI Components: Using inlines and dashboard chart widgets.
    • Data Operations: Performing bulk actions and managing file uploads.
    • Display Customization: Configuring specific display fields for admin models.
  2. FastAdmin Core Features Overview

    main

    FastAdmin provides a Django-Admin-style interface for modern Python web frameworks. Key capabilities include:

    • Familiar API: Uses attributes like list_display, list_filter, search_fields, fieldsets, readonly_fields, and inlines.
    • Multi-ORM Support: Native support for Tortoise ORM, Django ORM, SQLAlchemy (async), Pony ORM, and Yara ORM.
    • Authentication: Pluggable sign-in against your own user model with per-action permission hooks.
    • Rich UI: 20+ antd-based widgets (rich text, JSON, async select, etc.) via formfield_overrides.
    • File Handling: Storage-agnostic upload_file hooks and presigned-URL support via get_file_url.
    • Dashboards: Declarative charts (line, area, column, bar, pie) and action widgets.
    • Data Operations: Bulk actions and CSV/JSON export.
  3. Core features of FastAdmin

    main

    FastAdmin provides a Django-inspired admin experience for modern Python web frameworks. Key features include:

    • Familiar API: Uses concepts like list_display, list_filter, search_fields, inlines, and actions.
    • Framework-agnostic: Can be mounted into FastAPI, registered as a Flask blueprint, or included in Django urlpatterns.
    • ORM-agnostic: Supports Tortoise ORM, Django ORM, SQLAlchemy (async), Pony ORM, and Yara ORM.
    • Dashboard widgets: Declarative charts (line, area, column, bar, pie) powered by antd charts.
    • Uploads & exports: Built-in support for file/image uploads with custom storage hooks and CSV/JSON data exports.
  4. Configure chart and action properties

    main

    Depending on the widget_action_type, you use different property classes:

    Chart Properties

    Use WidgetActionChartProps(x_field, y_field, series_field=None, series_color=None) to map data rows to axes.

    • series_field: Used for multi-series charts.
    • series_color: A list or dict to pin specific colors to series.

    Action Properties

    Use WidgetActionProps(arguments=[WidgetActionArgumentProps(...)]) for Action widgets. This renders an input form. Each argument includes:

    • name
    • widget_type (see form widgets)
    • widget_props (optional)
    • parent_argument: An optional WidgetActionParentArgumentProps to conditionally show the argument based on another argument's value.

    Filters

    Use WidgetActionFilter(field_name, widget_type, widget_props=None) to render controls above the widget. Selected values are passed to the handler in the payload.query list.

  5. Choose the correct Admin class for your ORM

    main

    FastAdmin provides ORM-agnostic base classes and specialized subclasses for specific ORMs. Use the subclass that matches your database layer to ensure compatibility.

    Base Classes (ORM-agnostic)

    • ModelAdmin: Base class for model administration.
    • InlineModelAdmin: Base class for inline administration.

    ORM-Specific Classes

    • Tortoise ORM: TortoiseModelAdmin, TortoiseInlineModelAdmin
    • Django ORM: DjangoModelAdmin, DjangoInlineModelAdmin
    • SQLAlchemy (async): SqlAlchemyModelAdmin, SqlAlchemyInlineModelAdmin
    • Pony ORM: PonyORMModelAdmin, PonyORMInlineModelAdmin
    • Yara ORM: YaraOrmModelAdmin, YaraOrmInlineModelAdmin
  6. Mount FastAdmin in Flask

    main

    To integrate FastAdmin into a Flask application, register the flask_app as a blueprint with a preferred URL prefix.

    from fastadmin import flask_app as admin_app
    app.register_blueprint(admin_app, url_prefix="/admin")
  7. Mount FastAdmin in Django

    main

    To integrate FastAdmin into a Django project, use get_django_admin_urls within your urlpatterns in urls.py.

    from fastadmin import get_django_admin_urls as get_admin_urls
    from django.urls import path
    
    urlpatterns = [
        path("admin/", get_admin_urls()),
    ]
  8. Run the Django + Django ORM Example

    main

    To run the Django + Django ORM example project, use make to handle the environment setup and server execution. The example uses an in-memory SQLite database and pre-configures a superuser with the credentials admin/admin. Environment variables are managed within the __init__.py file of the package.

    1. Install dependencies: Creates a virtual environment using Poetry.
    2. Start the server: Launches the Django development server.
    3. Access the dashboard: Navigate to http://127.0.0.1:8090/admin/ in your browser.
    make install  # Create virtualenv with Poetry
    make run      # Start the Django dev server
  9. Implement file and image uploads

    main

    To handle file or image uploads, set the field to use WidgetType.UploadFile or WidgetType.UploadImage in formfield_overrides, and implement the upload_file method on your ModelAdmin.

    The upload_file method receives the raw file content and must return the string (URL or key) that should be stored in the database field.

    class UserAdmin(TortoiseModelAdmin):
        formfield_overrides = {
            "attachment": (WidgetType.UploadFile, {"required": False}),
        }
    
        async def upload_file(
            self,
            field_name: str,
            file_name: str,
            file_content: bytes,
            obj=None,  # None on the add page; the existing instance on the change page
        ) -> str:
            path = Path("uploads") / file_name
            path.write_bytes(file_content)
            return f"/uploads/{file_name}"
  10. Register ORM models with FastAdmin

    main

    To make a model visible in the FastAdmin dashboard, you must create a model admin class that inherits from the base class corresponding to your ORM and decorate it with @register(Model).

    Supported ORM Base Classes

    ORMModel adminInline admin
    Tortoise ORMTortoiseModelAdminTortoiseInlineModelAdmin
    Django ORMDjangoModelAdminDjangoInlineModelAdmin
    SQLAlchemySqlAlchemyModelAdminSqlAlchemyInlineModelAdmin
    Pony ORMPonyORMModelAdminPonyORMInlineModelAdmin
    Yara ORMYaraOrmModelAdminYaraOrmInlineModelAdmin

    Special Configuration

    • SQLAlchemy: When registering, you must pass the async session maker: @register(Model, sqlalchemy_sessionmaker=sqlalchemy_sessionmaker).
    • Multiple ORMs: If your project uses multiple ORMs simultaneously, set the model_name_prefix attribute on your model admin class to prevent name collisions in the dashboard.
    from fastadmin import TortoiseModelAdmin, register
    
    from models import Tournament
    
    @register(Tournament)
    class TournamentAdmin(TortoiseModelAdmin):
        list_display = ("id", "name")
  11. Define bulk actions with the @action decorator

    main

    Bulk actions allow you to perform operations on multiple selected records. Define them using the @action decorator and list the method names in the actions attribute of your ModelAdmin.

    Action Response Types

    An action can return:

    • None: No special response.
    • ActionResponseSchema with type=ActionResponseType.MESSAGE: Displays a message to the user.
    • ActionResponseSchema with type=ActionResponseType.DOWNLOAD_BASE64: Triggers a file download (requires data as base64 content and file_name).

    Running actions without selection

    By default, the Apply button is disabled until rows are selected. To allow running an action on all objects without selecting any, set requires_selection=False. In this case, the ids argument will be an empty list.

    Configuration options

    • actions: Tuple of action method names.
    • actions_on_top: Boolean (default False) to show the actions bar at the top.
    • actions_on_bottom: Boolean (default False) to show the actions bar at the bottom.
    • actions_selection_counter: Boolean to show how many items are selected.
    from fastadmin import TortoiseModelAdmin, action, register
    from fastadmin import ActionResponseSchema, ActionResponseType
    
    @register(Story)
    class StoryAdmin(TortoiseModelAdmin):
        actions = ("make_published",)
        actions_on_top = False        # actions bar at the top of the list page
        actions_on_bottom = True      # actions bar at the bottom
        actions_selection_counter = True
    
        @action(description="Mark selected stories as published")
        async def make_published(self, objs: list) -> ActionResponseSchema | None:
            for obj in objs:
                obj.status = "published"
                await obj.save()
            return ActionResponseSchema(type=ActionResponseType.MESSAGE, data="Published!")
    
        @action(description="Delete all stories", requires_selection=False)
        async def delete_all(self, ids: list) -> None:
            await Story.all().delete()