Layout API Overview¶
The Layout API provides a powerful, declarative way to customize form layouts in django-admin-deux. It supports progressive enhancement: basic layouts work without plugins, while advanced features like inline editing and conditional fields are enabled when you install the djadmin-formset plugin.
Key Features¶
Core Features (No Plugin Required)¶
- ✅ Fieldsets - Group fields with legends and descriptions
- ✅ Rows - Horizontal field layouts using flexbox
- ✅ Field Customization - Labels, widgets, help text, CSS classes
- ✅ Widget Shortcuts - Use string names like
'textarea','email' - ✅ Django Admin Migration - Automatic conversion of
fieldsetsto Layout
Plugin Features (Requires djadmin-formset)¶
- ✅ Collections - Inline editing of related objects
- ✅ Conditional Fields - Show/hide fields based on values (
show_if,hide_if) - ✅ Computed Fields - Auto-calculate values (
calculate) - ✅ Client-side Validation - Instant feedback without page refresh
- ✅ Drag-and-drop - Reorder inline items with
is_sortable
Quick Start¶
Simple Layout (Core Only)¶
from djadmin import ModelAdmin, register, Layout, Field, Fieldset, Row
@register(Author)
class AuthorAdmin(ModelAdmin):
layout = Layout(
Fieldset('Personal Information',
Row(
Field('first_name', css_classes=['flex-1', 'pr-2']),
Field('last_name', css_classes=['flex-1', 'pl-2']),
),
Field('birth_date', label='Date of Birth'),
),
Fieldset('Biography',
Field('bio', widget='textarea', attrs={'rows': 8}),
),
)
Result: Renders with fieldsets and flexbox rows. No plugin required!
With Inline Editing (Requires Plugin)¶
from djadmin import ModelAdmin, register, Layout, Field, Collection
@register(Author)
class AuthorAdmin(ModelAdmin):
layout = Layout(
Field('name'),
Field('birth_date'),
Collection('books',
model=Book,
fields=['title', 'isbn', 'published_date'],
is_sortable=True,
),
)
Without plugin: Error at startup with clear installation instructions With plugin: Full inline editing with drag-and-drop ordering
Installation¶
Core Only¶
With Plugin (Recommended)¶
Or install separately:
Components¶
The Layout API consists of 5 main components:
- Field - A single form field with customization options
- Fieldset - Groups fields with optional legend
- Row - Horizontal layout using flexbox
- Collection - Inline editing (requires plugin)
- Layout - Top-level container
Progressive Enhancement¶
The Layout API is designed for progressive enhancement:
Without Plugin With Plugin
├─ Fieldsets: ✓ ├─ Everything core does, PLUS:
├─ Rows: ✓ ├─ Collections (inline editing)
├─ Fields: ✓ ├─ Conditional fields (show_if/hide_if)
├─ Widget shortcuts: ✓ ├─ Computed fields (calculate)
├─ Collections: ✗ (warning) ├─ Client-side validation
├─ Conditional: ✗ (error) └─ Drag-and-drop ordering
└─ Computed: ✗ (error)
Feature Validation¶
django-admin-deux validates features at startup to prevent runtime errors:
# This will fail at startup if plugin not installed
class ProductAdmin(ModelAdmin):
layout = Layout(
Field('name'),
Field('weight', show_if=".type === 'physical'"), # Needs plugin!
)
Error message:
ImproperlyConfigured: Form for Product requires features that are not available:
• Conditional fields (show_if/hide_if) require the djadmin-formset plugin.
Install with: pip install django-admin-deux[djadmin-formset]
This fail-fast approach prevents production issues and guides developers to install required plugins.
Migration from Django Admin¶
The Layout API provides automatic conversion of Django admin fieldsets:
# Old Django admin code - JUST COPY IT!
class BookAdmin(admin.ModelAdmin):
fieldsets = (
('Personal', {
'fields': ('name', ('first_name', 'last_name'))
}),
)
# New djadmin - SAME CODE!
class BookAdmin(ModelAdmin):
fieldsets = ( # ← Automatically converts to Layout
('Personal', {
'fields': ('name', ('first_name', 'last_name'))
}),
)
The metaclass automatically converts fieldsets to Layout at class creation time.
See Django Admin Migration Guide for details.
Architecture¶
Core Rendering (Limited)¶
When no plugin is installed, layouts are rendered using Django templates:
- Templates:
djadmin/templates/djadmin/includes/ form_layout.html- Iterates layout itemsform_field.html- Single field renderingform_row.html- Flexbox row containerform_fieldset.html- Fieldset with legend-
form_collection_warning.html- Warning for collections -
Capabilities:
- ✅ Fieldsets as
<fieldset>tags - ✅ Rows as flexbox containers
- ✅ Basic field rendering
- ✅ Widget shortcuts
- ❌ Collections show warning
- ❌ Conditional fields cause error
- ❌ Computed fields cause error
Plugin Rendering (Full Featured)¶
When djadmin-formset is installed:
- Strategy: Plugin takes over ALL forms via
djadmin_modify_form_classhook - Conversion: Layout → django-formset FormCollection
- Renderer: DjAdminFormRenderer for themed rendering
- Capabilities: Everything core does, plus all advanced features
Next Steps¶
- Component Reference - Detailed API for each component
- Django Admin Migration - Convert existing Django admin code
- Examples - Real-world usage patterns
- Plugin Development - Extend the Layout API
Why Layout API?¶
Problems with Django Admin¶
- Rigid fieldsets - Tuple syntax is hard to read and maintain
- No horizontal layouts - All fields are stacked vertically
- No inline customization - Limited control over inline appearance
- No conditional logic - Can't show/hide fields dynamically
Layout API Solutions¶
- ✅ Declarative - Clean, readable Python syntax
- ✅ Flexible - Fieldsets, rows, and nested layouts
- ✅ Progressive - Start simple, add features as needed
- ✅ Type-safe - Dataclasses with validation
- ✅ Extensible - Plugin system for advanced features
- ✅ Compatible - Automatic Django admin migration
Philosophy¶
The Layout API follows these principles:
- Progressive Enhancement - Core features work standalone, plugins add capabilities
- Fail Fast - Feature validation at startup, not runtime
- Developer Experience - Clear error messages guide developers
- Flexibility - Support both simple and complex use cases
- Compatibility - Easy migration from Django admin
Support¶
- Documentation: Full documentation
- Examples: Usage examples
- Troubleshooting: Common issues
- Codeberg: Report issues