Django admin¶
Register a ModelSerializer in the Django admin with one decorator. The list
columns, search, filters, read-only fields and inlines come from its Schemas.
Register a model¶
Add @register_admin above the model:
from django.db import models
from ninja_aio import ModelSerializer, SchemaConfig
from ninja_aio.admin import register_admin
@register_admin
class Article(ModelSerializer):
title = models.CharField(max_length=200)
body = models.TextField()
is_published = models.BooleanField(default=False)
views = models.IntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(
Category, on_delete=models.CASCADE, related_name="articles"
)
class Schemas:
create = SchemaConfig(fields=["title", "body", "category"])
read = SchemaConfig(
fields=["id", "title", "is_published", "views", "created_at", "category"]
)
update = SchemaConfig(
optionals=[("title", str), ("body", str), ("is_published", bool)]
)
The article now shows up in the admin. You need django.contrib.admin in
INSTALLED_APPS and the admin URLs, as in any Django project.
Deprecated in 3.0
from ninja_aio import register_admin still works but is deprecated. Import it from ninja_aio.admin.
Know what is generated¶
| Option | Built from |
|---|---|
list_display |
The read fields and customs. Many-to-many and reverse relations are left out |
search_fields |
Text fields in read: CharField, TextField, SlugField, EmailField, URLField |
list_filter |
Fields in read that are boolean, date, datetime, foreign key, one-to-one, many-to-many or have choices |
readonly_fields |
Fields in read that are not in the generated update schema (its fields, optionals, and fields allowed through excludes), and all customs. The primary key is never read-only |
inlines |
Every model with a foreign key to this one. One-to-one relations use a stacked inline, the others a tabular inline |
filter_horizontal |
Many-to-many fields declared on this model |
The detail schema is not used. For the Article above you get:
| Option | Value |
|---|---|
list_display |
id, title, is_published, views, created_at, category |
search_fields |
title |
list_filter |
is_published, created_at, category |
readonly_fields |
views, created_at, category |
title and is_published are editable because they are in update.
Inlines¶
When you register Category too, its page gets an inline with its articles.
When the child model is a
ModelSerializer, the inline shows its update fields, or its create fields
if update has none. The foreign key back to the parent is hidden. Plain
Django models show all their editable fields.
Override options¶
Pass any ModelAdmin option to the decorator. It replaces the generated
value:
@register_admin(
list_per_page=50,
readonly_fields=("views", "created_at"),
list_filter=("is_published",),
)
class Article(ModelSerializer):
...
Use inlines=() or filter_horizontal=() to turn those off.
Register on your own admin site¶
Pass site to register on a custom AdminSite instead of admin.site:
from django.contrib.admin import AdminSite
class BlogAdminSite(AdminSite):
site_header = "Blog admin"
blog_admin = BlogAdminSite(name="blog_admin")
from .admin import blog_admin
@register_admin(site=blog_admin)
class Article(ModelSerializer):
...
You can also call it as a function, for example in admin.py:
from ninja_aio.admin import register_admin
from .models import Article
register_admin(Article, site=blog_admin, list_per_page=50)
Build the ModelAdmin yourself¶
as_admin() returns the generated ModelAdmin class without registering it.
It takes the same overrides:
from django.contrib import admin
from .models import Article
admin.site.register(Article, Article.as_admin(list_per_page=50))
Subclass it to add methods or actions:
@admin.register(Article)
class ArticleAdmin(Article.as_admin()):
actions = ["publish"]
@admin.action(description="Publish selected articles")
def publish(self, request, queryset):
queryset.update(is_published=True)
Use the admin with a Serializer¶
register_admin and as_admin() work only with ModelSerializer.
register_admin raises TypeError for any other class. For a model described
by a Serializer, register the model with Django's admin yourself:
from django.contrib import admin
from .models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ("id", "title", "is_published")
search_fields = ("title",)