Create new PluginViews to allow plugins to extend base view classes #4800

Closed
opened 2025-12-29 19:20:44 +01:00 by adam · 8 comments
Owner

Originally created by @DanSheps on GitHub (Apr 20, 2021).

Originally assigned to: @DanSheps on GitHub.

NetBox version

v2.11.0

Feature type

Change to existing functionality

Proposed functionality

Create separate view classes for plugins to extend and provide base functionality to plugins. This class would provide a consistent api for plugin developers to extend while maintaining compatibility with the existing base classes.

Use case

Currently there is no way for plugins to extend NetBox view classes

Database changes

None expected

External dependencies

No response

Originally created by @DanSheps on GitHub (Apr 20, 2021). Originally assigned to: @DanSheps on GitHub. ### NetBox version v2.11.0 ### Feature type Change to existing functionality ### Proposed functionality Create separate view classes for plugins to extend and provide base functionality to plugins. This class would provide a consistent api for plugin developers to extend while maintaining compatibility with the existing base classes. ### Use case Currently there is no way for plugins to extend NetBox view classes ### Database changes None expected ### External dependencies _No response_
adam added the status: acceptedtype: featuretopic: plugins labels 2025-12-29 19:20:44 +01:00
adam closed this issue 2025-12-29 19:20:45 +01:00
Author
Owner

@jeremystretch commented on GitHub (Apr 28, 2021):

This needs to be fleshed out before we can look at assigning a milestone.

  • What specific views are we introducing?
  • Where will they live?
  • How will they be documented?
@jeremystretch commented on GitHub (Apr 28, 2021): This needs to be fleshed out before we can look at assigning a milestone. * What specific views are we introducing? * Where will they live? * How will they be documented?
Author
Owner

@DanSheps commented on GitHub (May 18, 2021):

Blocked by 2.12

@DanSheps commented on GitHub (May 18, 2021): Blocked by 2.12
Author
Owner

@maximumG commented on GitHub (Jun 28, 2021):

When working on a netbox plugin, I also seek to re-use existings netbox UI components. I know it is not officially supported but I'd like to provide a consistent UI and UX while keeping code simple.

I was able to use the generic views that netbox provides to create the following plugins view.

  • ListView, parent class netbox.views.generic.ObjectListView
  • EditView, parent class netbox.views.generic.ObjectEditView
  • DeleteView, parent class netbox.views.generic.ObjectDeleteView

My conclusion on this work is that re-using existing Views is quite simple. The only issue that I ran mostly into was the top-right buttons in the ListView (add, edit, delete). Actually, these buttons are hyperlinks which are automatically generated and not "plugin aware".

To overcome this, I had to register a new django template filter named plugin_validated_viewname. This filter allows URL in the buttons to be "plugin-aware". I duplicated the django template netbox/template/generic/object_list.html and replace the validated_viewname filter with my own filter plugin_validated_viewname.

@register.filter()
def plugin_validated_viewname(model, action):
    """Return the view name for :
        * the given model and action if valid
        * or the given model and action if valid inside a plugin
        * or None if invalid.
    """
    core_viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}'
    plugin_viewname = f'plugins:{model._meta.app_label}:{model._meta.model_name}_{action}'
    try:
        # Validate and return the view name. We don't return the actual URL yet because many of the templates
        # are written to pass a name to {% url %}.
        reverse(core_viewname)
        return core_viewname
    except NoReverseMatch:
        try:
            reverse(plugin_viewname)
            return plugin_viewname
        except NoReverseMatch:
            return None
@maximumG commented on GitHub (Jun 28, 2021): When working on a netbox plugin, I also seek to re-use existings netbox UI components. **I know it is not officially supported** but I'd like to provide a consistent UI and UX while keeping code simple. I was able to use the generic views that netbox provides to create the following plugins view. * `ListView`, parent class `netbox.views.generic.ObjectListView` * `EditView`, parent class `netbox.views.generic.ObjectEditView` * `DeleteView`, parent class `netbox.views.generic.ObjectDeleteView` My conclusion on this work is that re-using existing Views is quite simple. **The only issue that I ran mostly into was the top-right buttons** in the ListView (add, edit, delete). Actually, these buttons are hyperlinks which are automatically generated and not "plugin aware". To overcome this, I had to register a new django template filter named _plugin_validated_viewname_. This filter allows URL in the buttons to be "plugin-aware". I duplicated the django template _netbox/template/generic/object_list.html_ and replace the _validated_viewname_ filter with my own filter _plugin_validated_viewname_. ```python @register.filter() def plugin_validated_viewname(model, action): """Return the view name for : * the given model and action if valid * or the given model and action if valid inside a plugin * or None if invalid. """ core_viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}' plugin_viewname = f'plugins:{model._meta.app_label}:{model._meta.model_name}_{action}' try: # Validate and return the view name. We don't return the actual URL yet because many of the templates # are written to pass a name to {% url %}. reverse(core_viewname) return core_viewname except NoReverseMatch: try: reverse(plugin_viewname) return plugin_viewname except NoReverseMatch: return None ```
Author
Owner

@hagbarddenstore commented on GitHub (Sep 21, 2021):

I've also done some modifications to make this issue work.

I've edited the following files:

# utilities/templatetags/helpers.py

@register.filter()
def validated_viewname(model, action):
    """
    Return the view name for the given model and action if valid, or None if invalid.
    """
    viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}'

    if model._meta.app_label in settings.PLUGINS:
        viewname = "plugins:{}".format(viewname)

    try:
        # Validate and return the view name. We don't return the actual URL yet because many of the templates
        # are written to pass a name to {% url %}.
        reverse(viewname)
        return viewname
    except NoReverseMatch:
        return None
# utilities/templatetags/buttons.py

def _get_viewname(instance, action):
    """
    Return the appropriate viewname for adding, editing, or deleting an instance.
    """

    # Validate action
    assert action in ('add', 'edit', 'delete')

    viewname = "{}:{}_{}".format(
        instance._meta.app_label, instance._meta.model_name, action
    )

    if instance._meta.app_label in settings.PLUGINS:
        viewname = "plugins:{}".format(viewname)

    return viewname

Not entirely sure this is the best solution, since it will allow plugins to override core Netbox URLs. This shouldn't be a large issue though, given that the application names needs to be unique without the plugins prefix.

@hagbarddenstore commented on GitHub (Sep 21, 2021): I've also done some modifications to make this issue work. I've edited the following files: ```python # utilities/templatetags/helpers.py @register.filter() def validated_viewname(model, action): """ Return the view name for the given model and action if valid, or None if invalid. """ viewname = f'{model._meta.app_label}:{model._meta.model_name}_{action}' if model._meta.app_label in settings.PLUGINS: viewname = "plugins:{}".format(viewname) try: # Validate and return the view name. We don't return the actual URL yet because many of the templates # are written to pass a name to {% url %}. reverse(viewname) return viewname except NoReverseMatch: return None ``` ```python # utilities/templatetags/buttons.py def _get_viewname(instance, action): """ Return the appropriate viewname for adding, editing, or deleting an instance. """ # Validate action assert action in ('add', 'edit', 'delete') viewname = "{}:{}_{}".format( instance._meta.app_label, instance._meta.model_name, action ) if instance._meta.app_label in settings.PLUGINS: viewname = "plugins:{}".format(viewname) return viewname ``` Not entirely sure this is the best solution, since it will allow plugins to override core Netbox URLs. This shouldn't be a large issue though, given that the application names needs to be unique without the `plugins` prefix.
Author
Owner

@DanSheps commented on GitHub (Sep 22, 2021):

While I applaud both efforts, for now, if you want to re-use, please use the netbox-plugin-extensions plugin. This is an unofficial plugin that allows reuse of the Netbox templates & components, but will prevent any namespace collisions with anything we develop down the road.

@DanSheps commented on GitHub (Sep 22, 2021): While I applaud both efforts, for now, if you want to re-use, please use the netbox-plugin-extensions plugin. This is an unofficial plugin that allows reuse of the Netbox templates & components, but will prevent any namespace collisions with anything we develop down the road.
Author
Owner

@maximumG commented on GitHub (Sep 22, 2021):

Your netbox-plugin-extensions is for me clearly the way to go in order to build easily 'Netbox like' WebUI. We had the same idea internally: to create some kind of templating plugin which would have been used as seed for all other internal plugins, but we are definitely looking forwarding with this public plugin.

@maximumG commented on GitHub (Sep 22, 2021): Your _netbox-plugin-extensions_ is for me clearly the way to go in order to build easily 'Netbox like' WebUI. We had the same idea internally: to create some kind of templating plugin which would have been used as seed for all other internal plugins, but we are definitely looking forwarding with this public plugin.
Author
Owner

@DanSheps commented on GitHub (Sep 22, 2021):

Feel free to suggest any improvements

@DanSheps commented on GitHub (Sep 22, 2021): Feel free to suggest any improvements
Author
Owner

@jeremystretch commented on GitHub (Jan 12, 2022):

I spoke with @DanSheps and we agreed to replace this FR with #8334, which proposes that we expose NetBox's existing generic views rather than replicating them specifically for plugins. #8334 will be tagged as a v3.2 milestone.

@jeremystretch commented on GitHub (Jan 12, 2022): I spoke with @DanSheps and we agreed to replace this FR with #8334, which proposes that we expose NetBox's existing generic views rather than replicating them specifically for plugins. #8334 will be tagged as a v3.2 milestone.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#4800