Migration Steps¶
1. Identify View Components¶
First, analyze your existing view to identify its components:
- Object fields display
- Related object tables
- Custom field groups
- Statistics/counts
- Text content (descriptions, notes)
- Custom template sections
2. Choose Appropriate Panels¶
Map your existing components to UI Framework panels:
Current Feature | UI Framework Panel |
---|---|
Basic field display | ObjectFieldsPanel |
Related object tables | ObjectsTablePanel |
Key-value data | KeyValueTablePanel |
Grouped fields | GroupedKeyValueTablePanel |
Statistics of related models | StatsPanel |
Markdown/JSON/text content | TextPanel or ObjectTextPanel |
3. Convert Views¶
1. Update your view class¶
# Before
from nautobot.core.views import generic
class MyDetailView(generic.ObjectView):
template_name = 'myapp/detail.html'
# After
from nautobot.apps import views
class MyDetailView(views.ObjectDetailViewMixin):
object_detail_content = ObjectDetailContent(
panels=[
# Panel definitions
]
)
2. Move context data into panels¶
In new approach most of the logic that currently sits in the get_context_data
can be removed
and appropriate panel will handle data generation automatically.
Example¶
Before:
views.py
from nautobot.core.views import generic
from my_app.models import Tenant, Circuit, Cluster, Device
class TenantView(generic.ObjectView):
queryset = Tenant.objects.select_related("tenant_group")
def get_extra_context(self, request, instance):
stats = {
"circuit_count": Circuit.objects.restrict(request.user, "view").filter(tenant=instance).count(),
"cluster_count": Cluster.objects.restrict(request.user, "view").filter(tenant=instance).count(),
"device_count": Device.objects.restrict(request.user, "view").filter(tenant=instance).count(),
}
return {"stats": stats, **super().get_extra_context(request, instance)}
After:
views.py
from nautobot.apps import views
from my_app.models import Tenant, Circuit, Cluster, Device
class TenantView(views.ObjectDetailViewMixin):
queryset = Tenant.objects.select_related("tenant_group")
object_detail_content = ObjectDetailContent(
panels=(
StatsPanel(
weight=100,
label="Stats",
section=SectionChoices.RIGHT_HALF,
filter_name="tenant",
related_models=[
Circuit,
Cluster,
Device,
],
),
)
)
4. Layout Organization¶
By using panels weights and sections you can determine how your app will display data.
The panel weight determines the order of panels within a section and depends on the chosen layout.
Panels in the same section (left/right/full-width) will be arranged based on their weight,
with lower-weight panels appearing first,
but the layout choice
(TWO_OVER_ONE
or ONE_OVER_TWO
)
decides what sections will be at the top.
Organize your panels using sections and weights:
object_detail_content = ObjectDetailContent(
panels=[
# Left column
ObjectFieldsPanel(
weight=100,
section=SectionChoices.LEFT_HALF,
),
# Right column
StatsPanel(
weight=100,
section=SectionChoices.RIGHT_HALF,
),
# Full width at bottom
ObjectsTablePanel(
weight=200,
section=SectionChoices.FULL_WIDTH,
),
]
)
Migration Checklist¶
- [ ] Identify all template-based views to migrate
- [ ] Map current features to UI Framework panels
- [ ] Update view classes
- [ ] Verify all functionality works as before
- [ ] Remove deprecated template files
- [ ] Update documentation and tests