Skip to main content

Python and Ruby parity

The two backends implement the same contract, but not the same feature set. This page says which half of the frontend works against which backend, so a choice made here does not turn into a surprise later.

Core: identical​

Everything the generated admin is made of works the same on both sides:

FeaturePythonRuby
Resource, view and menu schemas✅✅
List / show / create / edit views✅✅
Boxes — simple, grid, tab, wizard, list, gallery, object, array✅✅
Custom and confirmed actions, action views✅✅
Filters, ordering, fulltext search with highlights✅✅
Diacritics-insensitive searchADMIN_SEARCH_UNACCENT_ENABLEDsearch_unaccent_enabled
Per-record permissions✅✅
ID-based read without can_read— (write a custom permission class)allow_read_by_id
Change historydjango-reversionPaperTrail
Cross-service referencesAdminUUIDRelatedFieldCross-service references
Rich text tokens✅✅
Image upload actions✅✅
User preferences — the user-preferences endpoints✅✅ (contrib module)
Aggregations — the /aggregate endpoint✅✅
dashboard_enabled on a resource✅✅ (dashboard_enabled in the DSL)
Chunked uploads — TUS / S3 multipart✅ (paid)✅ (paid gem)
caution

The two aggregate implementations answer the same contract but not on any database: both truncate dates and bucket numbers through PostgreSQL-specific SQL. The Ruby side also reads group_by straight from the query string, because Rails' parameter parser keeps only the last value of a repeated key.

caution

Chunked uploads answer the same field schema (options.upload) on both sides, but not the same storage model. Python resolves a provider per field against that field's own storage, so a model with fields on different storages can use S3 for one and tus for another; Ruby resolves a single provider for the whole app, from its one default ActiveStorage service. Both wire their upload endpoints in automatically once the package is installed, and both are paid.

Python only​

One subsystem exists only in the Django library. The frontend components that consume it are documented without a Ruby counterpart, because there is none:

FeatureWhat needs it on the frontend
AI integration — the prediction and assistant endpointsSchemaPredictiveTextInput, SchemaAiAssistantButton

This does not break a Ruby-backed admin — the frontend degrades instead: the AI components are only rendered for a field the schema marks as AI-backed, which a Ruby resource never does.

The same degradation applies to a resource that simply leaves the aggregation off: the endpoint answers 404 and useAggregate reports isUnsupported rather than an error, whichever backend serves it.

Enum coverage​

The Ruby enum lists are behind the contract on two points, so a schema key the Python library can emit is rejected by the Ruby schema validation:

EnumMissing in Ruby
ActionTypeai-assistant, export
FieldFormatTypedecimal, tree-relation, czech-id-card-number

The frontend understands all of them — the gap is on the emitting side only.

caution

The AI field options are the exception worth knowing about: the Ruby DSL accepts ai_source_fields and a field format of ai, so a schema can look AI-enabled. What Ruby has no equivalent of is the endpoint behind it — the prediction/ route and the ai-assistant action — so the input renders and then fails at request time. Declare those formats only against a Python backend, or implement the routes yourself.

What this means for a migration​

how-it-works says the same frontend build works against either backend. That holds for the generated admin — lists, forms, actions, menus, permissions, and since the Ruby contrib modules landed, backend-synced preferences, the aggregate endpoint the dashboard widgets read, and chunked uploads (with habarico-enterprise, picking a single provider, per the caution above). It does not hold for the AI features: moving a service from Django to Rails means giving them up or reimplementing their endpoints, and the enums above mean a field format or action type the Django schema emits may have no Ruby equivalent to move to.

Going the other way — Rails to Django — adds AI integration, and needs no frontend change to do it, because it is switched on by a flag or an endpoint the frontend already looks for.

See also​