Django-inspired server-rendered admin for FastAPI and MongoDB
Project description
FastAPI Mongo Admin
A Django-inspired, server-rendered admin framework for FastAPI and MongoDB.
v2.0.0 replaces the legacy React SPA with a Jinja2 + HTMX admin interface, a full ModelAdmin configuration API, pluggable authentication, and support for both async (Motor) and sync (PyMongo) MongoDB backends.
Screenshots
Key Features
- Django-like registry —
site.register(Model, AdminClass) - Server-rendered admin UI — changelist, add/change forms, delete confirmation, bulk actions
- List filters — choice, boolean, date, related, and custom
ListFilterclasses - Pydantic-driven forms — validation and schema inference from your models
- Field mapping — map model fields to different MongoDB keys
- Pluggable auth — wire any FastAPI
Dependsauthentication/authorization - Sync + async MongoDB —
mode="async"(Motor) ormode="sync"(PyMongo) - Customization — template overrides,
ModelAdminhooks, custom admin views - JSON API —
/admin/api/{collection}/for programmatic access (read-only by default; optional write methods for/docs)
Breaking Changes (v0.x → v2)
- React UI and
/admin-uimount removed; admin lives at/admin MongoAdminalias removed; useAdminSiteorsite- Built-in demo token auth removed; provide
auth_dependency - Legacy
/admin/collections/.../documentsroutes removed
Installation
# Using uv (recommended)
uv add fastapi-mongo-admin
# Or pip
pip install fastapi-mongo-admin
Quick Start
1. Define models and admin classes
from pydantic import BaseModel
from fastapi_mongo_admin import ModelAdmin, site, display, action
from fastapi_mongo_admin.admin.filters import ChoiceListFilter, DateFieldListFilter
class Product(BaseModel):
name: str
price: float
category: str
active: bool = True
class ProductAdmin(ModelAdmin):
model = Product
collection_name = "products"
list_display = ["name", "category", "price", "active"]
list_filter = ["category", "active"]
search_fields = ["name", "category"]
list_per_page = 25
choices = {
"category": [("books", "Books"), ("electronics", "Electronics")],
}
@display(description="Name")
def name_upper(self, obj: dict) -> str:
return str(obj.get("name", "")).upper()
@action("Deactivate selected")
async def deactivate_selected(self, request, queryset: list[dict]) -> None:
pass
site.register(Product, ProductAdmin)
2. Mount in FastAPI (async)
from fastapi import FastAPI
from motor.motor_asyncio import AsyncIOMotorClient
from fastapi_mongo_admin import mount_admin_app
app = FastAPI()
client = AsyncIOMotorClient("mongodb://localhost:27017")
database = client["my_db"]
async def get_database():
return database
mount_admin_app(app, get_database, admin_site=site, mode="async")
3. Sync MongoDB
from pymongo import MongoClient
from fastapi_mongo_admin import mount_admin_app
client = MongoClient("mongodb://localhost:27017")
db = client["my_db"]
mount_admin_app(app, lambda: db, admin_site=site, mode="sync")
Visit http://localhost:8000/admin/ for the admin index.
Authentication
Pass any FastAPI-compatible dependency:
from fastapi import Depends, HTTPException
async def get_admin_user():
# Your JWT/session validation here
return {"id": "user-1", "is_staff": True}
mount_admin_app(
app,
get_database,
admin_site=site,
auth_dependency=get_admin_user,
)
JSON API
Read endpoints are always available at /admin/api/{collection}/. By default only GET operations appear in OpenAPI (/docs).
Enable POST, PUT, PATCH, and DELETE routes (and Swagger documentation):
mount_admin_app(
app,
get_database,
admin_site=site,
auth_dependency=get_admin_user,
api_write_methods=True,
)
| Method | URL | Description |
|---|---|---|
GET |
/admin/api/{collection}/ |
Paginated list (page, q) |
GET |
/admin/api/{collection}/{id} |
Single document |
POST |
/admin/api/{collection}/ |
Create (when api_write_methods=True) |
PUT |
/admin/api/{collection}/{id} |
Update |
PATCH |
/admin/api/{collection}/{id} |
Partial update |
DELETE |
/admin/api/{collection}/{id} |
Delete |
Write requests use the same Pydantic validation and ModelAdmin permission hooks as the HTML admin.
Override per-model permissions on ModelAdmin:
class ProductAdmin(ModelAdmin):
def has_add_permission(self, request, user=None) -> bool:
return bool(user and user.get("is_staff"))
ModelAdmin Options
| Option | Description |
|---|---|
model |
Pydantic model for validation |
collection_name |
MongoDB collection (required) |
list_display |
Changelist columns (fields or @display methods) |
list_display_links |
Clickable columns |
list_filter |
Field names or ListFilter subclasses |
search_fields |
Text search fields |
list_per_page |
Pagination size (default 25) |
ordering |
Default sort, e.g. ["-created_at"] |
date_hierarchy |
Date drill-down field |
list_select_related |
{"field": "collection"} for related lookups |
fieldsets |
Grouped change form layout |
readonly_fields |
Non-editable fields |
field_mapping |
Model field → DB field mapping |
actions |
Bulk action method names |
choices |
Choice lookups for filters/forms |
date_format |
Display format for date fields (default: 8 Apr 2026) |
datetime_format |
Display format for datetime fields (default: 8 Apr 2026, 7:32pm) |
Date and Time Display
date and datetime fields are formatted automatically on changelists and readonly form fields. Form inputs still use ISO values for HTML date/datetime pickers.
Default formats:
- Date:
8 Apr 2026 - Datetime:
8 Apr 2026, 7:32pm
Customize per model:
class OrderAdmin(ModelAdmin):
date_format = "j M Y" # Django-style tokens
datetime_format = "%d/%m/%Y %H:%M" # or standard strftime
Override completely:
def format_datetime_value(self, value) -> str:
return my_formatter(value)
Template Customization
from pathlib import Path
site = AdminSite(template_dirs=[Path("myapp/templates")])
class ProductAdmin(ModelAdmin):
change_list_template = "myapp/admin/product_change_list.html"
Register custom views:
async def reports(request):
return {"report": "data"}
site.register_view("Reports", "/reports/", reports)
URL Scheme
| URL | View |
|---|---|
GET /admin/ |
Admin index |
GET /admin/{collection}/ |
Changelist |
GET /admin/{collection}/add/ |
Add form |
GET/POST /admin/{collection}/{id}/change/ |
Change form |
POST /admin/{collection}/{id}/delete/ |
Delete |
POST /admin/{collection}/action/ |
Bulk actions |
GET /admin/api/{collection}/ |
JSON list API |
GET /admin/api/{collection}/{id} |
JSON detail API |
POST/PUT/PATCH/DELETE /admin/api/... |
JSON write API (api_write_methods=True) |
Development
make install # uv sync --group dev
make test # pytest
make lint # ruff
make secure # bandit + pysentry-rs
make docs # build Sphinx HTML docs
make help # list all targets
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fastapi_mongo_admin-2.0.2.tar.gz.
File metadata
- Download URL: fastapi_mongo_admin-2.0.2.tar.gz
- Upload date:
- Size: 527.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cf5dbfa7e5d855ad373482c6d711eb2bf69d59a2d2f7e15893586427926756f7
|
|
| MD5 |
6ed72b84c87e97c285e8a6c6c41c40c0
|
|
| BLAKE2b-256 |
df77e69409200793b19a721c8336e615fdb04bba5206b0113794d0addfa723d2
|
File details
Details for the file fastapi_mongo_admin-2.0.2-py3-none-any.whl.
File metadata
- Download URL: fastapi_mongo_admin-2.0.2-py3-none-any.whl
- Upload date:
- Size: 537.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d94e34c68f3f8385b3c24548e0fd19ecf5d9ebf6874b3957778e28402da9400
|
|
| MD5 |
9ac93041154ac3e399974f223d71fd17
|
|
| BLAKE2b-256 |
469d7c41fb06b57248a717a4fac796285fee3d655d0ce31264f78132d4ef66c9
|