netbox-plugin-tutorial icon indicating copy to clipboard operation
netbox-plugin-tutorial copied to clipboard

Demonstrate adding a custom tabbed view to a core model (v3.4)

Open jeremystretch opened this issue 2 years ago • 2 comments

NetBox v3.4 introduced the ability for plugins to register custom views that appear as tabs on core model views (FR #9072).

jeremystretch avatar Feb 03 '23 13:02 jeremystretch

Hi!

I am trying to use this feature but I can't get it to work. What I want to do is adding a tab on tenants that lists (with a table I created) some related objects.

I tried something like this (in myplugin/views.py) inspired by netbox plugin documentation but it surely isn't the solution:

from tenancy.models import Tenant
from netbox.views import generic
from . import models, tables
from utilities.views import ViewTab, register_model_view

@register_model_view(Tenant, name='myview', path='some-other-stuff')
class MyView(generic.ObjectListView):
    queryset = models.PluginObject.objects.all()
    table = tables.PluginObjectTable
    tab = ViewTab(
        label='Other Stuff',
        badge=lambda obj: obj.stuff_related_name.count(),
        permission='myplugin.view_stuff'
    )

The tab does render with the correct count badge but I get an ObjectListView.get() got an unexpected keyword argument 'pk' error when trying to load the tab view.

Thanks to anybody that could help me 😄


EDIT: I finally got this to work by looking into the netbox code / other plugins code.

Here is my view:

@register_model_view(Tenant, name='myview', path='some-other-stuff')
class MyView(generic.ObjectChildrenView):
    queryset = Tenant.objects.all().prefetch_related('stuff_set')
    child_model = models.Stuff
    table = tables.StuffTable
    template_name = "myplugin/stuffchild.html"
    hide_if_empty = True
    tab = ViewTab(
        label='My Custom View',
        badge=lambda obj: obj.stuff_set.count(),
        permission='myplugin.view_stuff'
    )

    def get_children(self, request, parent):
        return parent.stuff_set.all()

and I added the following in template/myplugin/stuffchild.html:

{% extends 'generic/object.html' %}
{% load render_table from django_tables2 %}

{% block content %}
    <div class="card">
        <div class="card-body" id="object_list">
            {% render_table table %}
        </div>
    </div>
{% endblock content%}

I don't know if this is the right way to do but it works fine for me 😄

Bapths avatar Apr 19 '23 08:04 Bapths

Had the same issue, but wanted to comment, that one can use the generic template generic/object_children.html of netbox, if one just wants a list without any further content/buttons etc. This would replace the custom template of @Bapths .

mytlogos avatar Sep 25 '23 08:09 mytlogos