Überwachte maschinelle Übersetzung
Dieser Inhalt wurde maschinell übersetzt und basiert auf von Menschen kuratierten Glossaren und Styleguides. Da der Text nicht zeilenweise manuell überprüft wird, können gelegentlich Fehler oder unklare Formulierungen auftreten.
Bei etwaigen Abweichungen ist die ursprüngliche englische Version die maßgebliche Quelle.
Migration von Django Admin
Wenn Sie Django Admin kennen, wird Ihnen starlette-admin vertraut vorkommen. Beide erzeugen eine Admin-Oberfläche aus deklarativer Konfiguration pro Modell, und beide unterstützen Inline-Bearbeitung, Batch-Aktionen und Berechtigungen pro Anfrage.
Die Unterschiede sind struktureller Natur. starlette-admin läuft auf jeder ASGI-Anwendung, statt Django vorauszusetzen, arbeitet mit mehreren ORMs und erlaubt es Ihnen, Ihre eigene Authentifizierung anzubinden, statt ein eingebautes Benutzermodell vorzugeben.
Dieser Leitfaden ordnet jedes zentrale ModelAdmin-Konzept seiner starlette-admin-Entsprechung zu – mit Code im direkten Vergleich.
Mentales Modell
| Django-Admin-Konzept | starlette-admin-Entsprechung |
|---|---|
AdminSite |
Admin-Instanz, die in Ihrer Anwendung gemountet ist |
ModelAdmin |
ModelView-Unterklasse |
admin.site.register(Model, ModelAdmin) |
admin.add_view(MyView(Model)) |
admin.site.urls in urlpatterns |
admin.mount_to(app) |
| Django ORM | SQLAlchemy, SQLModel, MongoEngine, Beanie oder Tortoise ORM über starlette_admin.contrib.* |
__str__ am Modell |
__admin_repr__(self, request), das asynchron ist und die Anfrage berücksichtigt |
| Aus Modelfeldern abgeleitete Formularfelder | Felder, abgeleitet vom Backend-Converter, pro Feld anpassbar |
Registrieren eines Modells
from starlette_admin.contrib.sqla import Admin, ModelView
class PostView(ModelView):
fields = ["id", "title", "content", "published", "created_at"]
exclude_fields_from_list = ["content"]
searchable_fields = ["title", "content"]
admin = Admin(engine, title="Blog Admin", secret_key="change-me")
admin.add_view(PostView(Post, icon="fa fa-newspaper"))
admin.mount_to(app) # app is your FastAPI or Starlette instance
Zwei strukturelle Unterschiede fallen besonders auf:
- Eine Feldliste steuert jede Seite.
fieldsist die alleinige Quelle der Wahrheit. Für Abweichungen pro Seite verwenden Sie anschließendexclude_fields_from_list,exclude_fields_from_detail,exclude_fields_from_createundexclude_fields_from_edit. - Die
Admin-Instanz besitzt die Datenbank-Engine. Sie übergeben keine Session an die einzelnen Views.
Optionen der Listenseite
| Django Admin | starlette-admin | Hinweise |
|---|---|---|
list_display |
fields minus exclude_fields_from_list |
Eine einzige Feldliste steuert alle Seiten. |
list_display mit einem Callable oder @admin.display |
ComputedField oder getter= an einem beliebigen Feld |
Zum Beispiel ComputedField("full_name", getter=lambda request, obj: ...). Verwenden Sie getter= an einem typisierten Feld, etwa einem Datums- oder Bildfeld, um dessen Rendering beizubehalten. |
| Neuformatieren einer echten Spalte zur Anzeige | formatter= am Feld |
Ein dict[RequestAction, callable], sodass Liste, Detailansicht und Export unterschiedlich formatieren können. Django benötigt einen Callable plus admin_order_field, um die Sortierbarkeit zu erhalten; hier bleibt die Spalte sortierbar. |
search_fields |
searchable_fields |
Steuert sowohl die Volltextsuche als auch den Filter-Builder. |
list_filter |
searchable_fields kombiniert mit pro Feld gesetztem filters= |
Benutzer erhalten einen visuellen Builder mit verschachtelten AND-/OR-Gruppen statt einer festen Sidebar. Siehe Filter. |
ordering |
fields_default_sort |
Zum Beispiel sortiert fields_default_sort = [("created_at", True)] in absteigender Reihenfolge. |
admin_order_field / Sortierbarkeit |
sortable_fields |
Jedes Feld ist standardmäßig sortierbar. |
list_editable |
inline_editable_fields |
Benutzer wählen eine Zelle aus und bearbeiten sie direkt an Ort und Stelle. |
list_per_page |
page_size, page_size_options |
Steuert die Grenzen der Paginierung. |
date_hierarchy |
Datumsfilter wie between und in the past |
Eine eigene Drilldown-Leiste gibt es nicht; der Filter-Builder deckt diesen Fall ab. |
empty_value_display |
Ein formatter=-Eintrag oder null_template |
Formatter erhalten None-Werte und können daher einen Platzhalter einsetzen. null_template ersetzt stattdessen das gerenderte Markup. |
Formulare
| Django Admin | starlette-admin | Hinweise |
|---|---|---|
fields / exclude |
fields, exclude_fields_from_create, exclude_fields_from_edit |
Steuert die Sichtbarkeit von Formularfeldern. |
fieldsets |
form_layout |
Frei kombinierbar mit FieldsetWidget, TabsWidget, GridWidget und RowWidget. |
readonly_fields |
read_only=True am Feld |
Sie können das Feld auch aus den Create- und Edit-Views ausschließen. |
prepopulated_fields |
SlugField("slug", populate_from="title") |
Identisches Verhalten der Live-Slug-Erzeugung. |
autocomplete_fields, raw_id_fields |
Standardverhalten von HasOne / HasMany |
Relations-Widgets sind Select2-Eingabefelder mit serverseitiger Suche ab Werk. |
filter_horizontal / filter_vertical |
HasMany |
Wird als durchsuchbare Multi-Select-Komponente gerendert. |
formfield_overrides |
Explizite Einträge in der fields-Liste |
Ersetzen Sie das automatisch erkannte Feld direkt: fields = ["id", TextAreaField("bio")] |
| Eigene Formularvalidierung | validators= am Feld oder FormValidationError in Hooks |
Siehe Validators. |
to_python() des Formularfelds / eigene Typumwandlung |
parser= am Feld |
Ersetzt das Standard-Parsing des Felds für Formular oder Import, jeweils pro RequestAction. |
| Hilfetext im Modelformular | help_text= |
Für jede Felddefinition verfügbar. |
Fieldsets-Beispiel
form_layout geht über Fieldsets hinaus: Sie können damit Tabs, responsive Grids und verschachtelte Layouts erstellen. Siehe Formularlayout.
Inlines
starlette-admin erkennt den Fremdschlüssel, wenn dieser eindeutig ist, und unterstützt zusammengesetzte Fremdschlüssel. Fortgeschrittene Konfigurationen finden Sie unter Inline-Formulare.
Aktionen
from starlette_admin import ActionSelection, action, flash
class ArticleView(ModelView):
actions = ["make_published", "delete"]
@action(
name="make_published",
text="Mark selected articles as published",
confirmation="Publish the selected articles?",
)
async def make_published(
self, request: Request, selection: ActionSelection
) -> None:
for article in await selection.rows():
article.published = True
flash(request, "Articles published")
Wo Django Admin ein QuerySet übergibt, erhält der Handler in starlette-admin ein ActionSelection-Objekt. Es löst Zeilen, Primärschlüssel und aktive Filter verzögert (lazy) auf und verhält sich genauso, wenn ein Benutzer alle übereinstimmenden Datensätze auswählt.
Aktionen können außerdem ein eigenes HTML-Formular innerhalb des Bestätigungsdialogs rendern – in Django Admin entspräche das dem Bau einer separaten Zwischenseite. Für Operationen auf Zeilenebene verwenden Sie @row_action und @link_row_action; dafür existiert kein Pendant in Django Admin.
Berechtigungen und Authentifizierung
Django Admin delegiert an django.contrib.auth. starlette-admin zerlegt das Problem in zwei Teile: Ein AuthProvider beantwortet die Frage „Wer ist dieser Benutzer?“, und die Methoden pro View beantworten die Frage „Was darf dieser Benutzer tun?“.
| Django Admin | starlette-admin |
|---|---|
django.contrib.auth-Login |
AuthProvider (eingebaute Anmeldeseite) oder OAuthProvider (OIDC-Redirect-Flow) |
request.user |
request.state.admin_user |
has_module_permission |
is_accessible(request) am View |
has_view_permission |
can_view_detail(request) |
has_add_permission |
can_create(request) |
has_change_permission |
can_edit(request) |
has_delete_permission |
can_delete(request) |
get_readonly_fields pro Benutzer |
can_access_field(request, field) |
| Keine Entsprechung | can_export(request), can_import(request), is_action_allowed(request, name) |
Die folgende View beschränkt das Löschen auf Benutzer mit der Rolle admin:
class ArticleView(ModelView):
def can_delete(self, request: Request) -> bool:
return "admin" in request.state.admin_user.roles
Jede can_*-Methode erhält die Anfrage, sodass Ihre Autorisierungsentscheidungen auf den aktuellen Benutzer, HTTP-Header oder beliebige andere Angaben der Anfrage zugreifen können.
Save-Hooks und Signale
| Django Admin | starlette-admin | Hinweise |
|---|---|---|
save_model(request, obj, form, change) |
before_create / before_edit am View |
Nativ asynchron; empfängt die geparsten Formulardaten zusammen mit der Modellinstanz. |
delete_model |
before_delete |
Dient der Logik vor dem Löschen. |
post_save und andere Signale |
Events | Zum Beispiel überträgt admin.events.on(AdminEvent.AFTER_CREATE, handler) an alle Views. |
LogEntry-Änderungshistorie |
Bauen Sie sie mit dem Event-System | Abonnieren Sie AFTER_CREATE, AFTER_EDIT und AFTER_DELETE, um Ihre eigene Audit-Tabelle zu füllen. |
messages.success(request, ...) |
flash(request, ...) |
Siehe Flash-Nachrichten. |
Globale Konfiguration
| Django Admin | starlette-admin |
|---|---|
admin.site.site_header, site_title |
Admin(title="...") |
| Eigenes Logo über einen Template-Override | Admin(logo_url="...", login_logo_url="...", favicon_url="...") |
AdminSite.index_template |
Admin(index_view=...) mit Widgets für ein umfangreiches Dashboard |
Template-Overrides in templates/admin/ |
Admin(templates_dir="..."), siehe Templates |
Mehrere AdminSite-Instanzen |
Mehrere Admin-Instanzen, gemountet an unterschiedlichen Anwendungspfaden |
ModelAdmin.get_queryset |
get_list_query, get_count_query oder get_detail_query für das SQLAlchemy-Backend |
USE_I18N, LANGUAGES |
Admin(i18n_config=I18nConfig(default_locale="fr")) |
TIME_ZONE |
Admin(timezone_config=TimezoneConfig(...)), siehe i18n und Zeitzonen |
Was Sie durch den Wechsel gewinnen
- Durchgängig asynchron: Handler, Lifecycle-Hooks und Widget-Callbacks können alle Coroutines sein, die auf Ihrer bestehenden Event-Loop laufen – neben Ihren FastAPI-Endpoints.
- Datenbankflexibilität: Dieselbe Admin-Konfiguration gilt unabhängig davon, ob Sie SQLAlchemy, SQLModel, MongoDB über MongoEngine oder Beanie oder Tortoise ORM verwenden.
- Export und Import eingebaut: CSV, JSON und PDF, dazu Excel und weitere Formate über
tablib. Exportieren Sie Datensätze direkt oder importieren Sie Massendaten über einen Wizard mit vorangestellter Vorschau, der Validierung auf Zeilenebene erzwingt und optionale Upserts per Primärschlüssel unterstützt. Siehe Export und Import. - Dashboard-Widgets: Stat-Karten, ApexCharts und Layout-Grids lassen sich zu Indexseiten und Custom Views kombinieren, sodass Sie kein externes Theme-Paket benötigen, um ein Dashboard zu bauen. Siehe Custom Views und Widgets.
- Moderne Benutzeroberfläche: Tabler (Bootstrap 5) bietet Dark Mode, Umschalter für die Spaltensichtbarkeit und Suchhervorhebung ab Werk.
Was Sie selbst bereitstellen müssen
- Authentifizierung: Es gibt kein gebündeltes Benutzermodell und keine Berechtigungsdatenbank. Implementieren Sie
AuthProvider.authenticate()gegen den Datenspeicher, den Ihre Anwendung bereits verwendet. - Audit-Logging: starlette-admin erzeugt keine
LogEntry-Tabelle. Verbinden Sie das Event-System mit Ihrer eigenen Audit-Tabelle. - UI-Konfiguration auf Modellebene: Django-Komfortfunktionen wie
choices,verbose_nameund Validatoren auf Modellebene werden nicht übernommen. Deklarieren Sie sie stattdessen am starlette-admin-Feld, mitEnumField,label=undvalidators=.