cartapel vs Django admin

If your application is already a Django app, Django admin is very hard to beat, and this page will not pretend otherwise. It lives inside your codebase, shares your models, your auth and your deploy pipeline, and its ecosystem — import/export, simple-history, filters, themes — is enormous and mature after two decades.

The comparison only gets interesting when the database was not born from Django. Then Django admin asks you to run inspectdb, hand-correct the generated models, and keep them in sync with every migration anyone else ships — forever. The ORM layer, not the database, becomes the source of truth, and it drifts.

cartapel inverts that: the live schema is the model. It introspects Postgres, MySQL or MariaDB at boot, so a new column shows up without regenerating anything, and the panel runs as a single binary beside any stack — Rails, Go, Node, Elixir, or a database no application owns.

The Customize drawer in cartapel with the HCL tab open, showing the screen.hcl the visual editor writes
No models, no admin.py: the file the panel reads is the file you review — and you can write it by clicking.

Side by side

cartapel Django admin
What it needs to run One Rust binary A Django project, Python runtime and WSGI/ASGI server
Existing database you do not own Introspects the live schema; nothing to sync inspectdb, then hand-corrected models kept in sync forever
Databases Postgres, MySQL, MariaDB (+ ClickHouse read-only) Whatever Django supports, through models
Customization Visual editor or HCL by hand — both produce files in git, reviewed in PRs Python in git — ModelAdmin classes, full escape hatch
Audit log Built in — before/after diff, one-click revert LogEntry covers admin actions; full history via packages
Dashboards SQL tiles, charts and template variables Not built in
Ecosystem Young — widgets are small JS files you drop in Two decades of third-party packages
License MIT, free, no seats BSD, free

Yellow cells are nuanced — the sections below say why.

Where Django admin is the better answer

Where cartapel is the better answer

The same jobs, side by side

Glance left → right. Everything on the right is the whole customization — no model, no build step, no Python.

Expose a table Django needs a model · cartapel reads the live schema
Django
# models.py — or inspectdb forever
class Order(models.Model):
    customer = models.ForeignKey(...)
    status = models.CharField(...)
    total = models.DecimalField(...)
    placed_at = models.DateTimeField(...)

# admin.py
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    pass
cartapel
# screens/sales/orders/screen.hcl
# empty file → working list already
# (search, filters, sort, FKs as links)
Shape the list list_display / list_filter / ordering
Django
@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    list_display = (
        "id", "customer", "status",
        "total", "placed_at",
    )
    list_filter = ("status",)
    ordering = ("-placed_at",)
cartapel
list {
  columns = [
    "id", "customer_id", "status",
    "total", "placed_at",
  ]
  filters = ["status"]
  sort    = "-placed_at"
}
Bulk action @admin.action → action block
Django
@admin.action(description="Refund")
def refund(self, request, qs):
    qs.update(status="refunded")

class OrderAdmin(admin.ModelAdmin):
    actions = ["refund"]
cartapel
action "refund" {
  label   = "Refund"
  kind    = "update"
  set     = { status = "refunded" }
  confirm = "Refund {count} orders?"
}
Render a field readonly display method → widget block
Django
class OrderAdmin(admin.ModelAdmin):
    @admin.display(description="Status")
    def status_badge(self, obj):
        color = {"paid": "green",
                 "refunded": "red"}[obj.status]
        return format_html(
            '<span style="color:{}">{}</span>',
            color, obj.status)
cartapel
field "status" {
  widget = "badge"
  params = {
    colors = {
      paid     = "green"
      refunded = "red"
    }
  }
}

The short version

Pick Django admin if Your app is Django and the models already exist — stay on Django admin.

Pick cartapel if The database predates you, belongs to another stack, or nobody wants a Python app just to get a panel.

Try the live demo Get started GitHub

No login. Click anything — the demo resets on a schedule.

Questions people actually ask

Can I run cartapel next to an existing Django admin?
Yes, and it is a common shape: Django admin for the engineers who live in the codebase, cartapel for support and ops, with its own roles, column masking and audit trail. They read the same database and neither owns the schema.
Do I lose Django signals and model validation?
Yes — cartapel writes to the database, not through your ORM, so Python-level signals and validators do not fire. Constraints, triggers and defaults in the database still apply. If your invariants live only in Python, keep those tables out of cartapel or move the rule into the schema.
Does it handle Django auth tables?
It can browse them like any other table, but password hashing is a Django concern. Treat user credentials as read-only and mask hash columns; cartapel masks secret-shaped columns by default.
Is there an inspectdb equivalent?
There is nothing to run. Introspection happens at boot and on demand, so a migration shipped by another team is visible in the panel without a code change on your side.

Other comparisons

cartapel vs Retool

The open-source, self-hosted answer when what you actually needed was a database panel, not an app builder.

cartapel vs Metabase

Metabase answers questions about the data. cartapel changes it, safely, and writes down who did.

cartapel vs Directus

The closest philosophical neighbour — same introspection bet, a much larger surface, and a different licence.

cartapel vs NocoDB

A spreadsheet over your database, versus a reviewable panel over a schema you did not want touched.

cartapel vs Baserow

An open-source Airtable that wants to own the data, versus a panel over data that is already owned.

cartapel vs pgAdmin

Keep pgAdmin for engineers. cartapel is the one you can safely give to everyone else.

Everything on one page: the full matrix against all seven.