mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Introduce ViewTab
This commit is contained in:
parent
a0bae06ff7
commit
4c999daacd
@ -13,7 +13,7 @@ from extras.utils import is_taggable, register_features
|
|||||||
from netbox.signals import post_clean
|
from netbox.signals import post_clean
|
||||||
from utilities.json import CustomFieldJSONEncoder
|
from utilities.json import CustomFieldJSONEncoder
|
||||||
from utilities.utils import serialize_object
|
from utilities.utils import serialize_object
|
||||||
from utilities.views import register_model_view
|
from utilities.views import ViewTab, register_model_view
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ChangeLoggingMixin',
|
'ChangeLoggingMixin',
|
||||||
@ -300,9 +300,6 @@ def _register_features(sender, **kwargs):
|
|||||||
sender,
|
sender,
|
||||||
'journal',
|
'journal',
|
||||||
'netbox.views.generic.ObjectJournalView',
|
'netbox.views.generic.ObjectJournalView',
|
||||||
tab_label='Journal',
|
|
||||||
tab_badge=lambda x: x.journal_entries.count(),
|
|
||||||
tab_permission='extras.view_journalentry',
|
|
||||||
kwargs={'model': sender}
|
kwargs={'model': sender}
|
||||||
)
|
)
|
||||||
if issubclass(sender, ChangeLoggingMixin):
|
if issubclass(sender, ChangeLoggingMixin):
|
||||||
@ -310,7 +307,5 @@ def _register_features(sender, **kwargs):
|
|||||||
sender,
|
sender,
|
||||||
'changelog',
|
'changelog',
|
||||||
'netbox.views.generic.ObjectChangeLogView',
|
'netbox.views.generic.ObjectChangeLogView',
|
||||||
tab_label='Changelog',
|
|
||||||
tab_permission='extras.view_objectchange',
|
|
||||||
kwargs={'model': sender}
|
kwargs={'model': sender}
|
||||||
)
|
)
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
from django.utils.translation import gettext as _
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
from extras import forms, tables
|
from extras import forms, tables
|
||||||
from extras.models import *
|
from extras.models import *
|
||||||
|
from utilities.views import ViewTab
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'ObjectChangeLogView',
|
'ObjectChangeLogView',
|
||||||
@ -23,6 +25,10 @@ class ObjectChangeLogView(View):
|
|||||||
base_template: The name of the template to extend. If not provided, "{app}/{model}.html" will be used.
|
base_template: The name of the template to extend. If not provided, "{app}/{model}.html" will be used.
|
||||||
"""
|
"""
|
||||||
base_template = None
|
base_template = None
|
||||||
|
tab = ViewTab(
|
||||||
|
label=_('Changelog'),
|
||||||
|
permission='extras.view_objectchange'
|
||||||
|
)
|
||||||
|
|
||||||
def get(self, request, model, **kwargs):
|
def get(self, request, model, **kwargs):
|
||||||
|
|
||||||
@ -71,6 +77,11 @@ class ObjectJournalView(View):
|
|||||||
base_template: The name of the template to extend. If not provided, "{app}/{model}.html" will be used.
|
base_template: The name of the template to extend. If not provided, "{app}/{model}.html" will be used.
|
||||||
"""
|
"""
|
||||||
base_template = None
|
base_template = None
|
||||||
|
tab = ViewTab(
|
||||||
|
label=_('Journal'),
|
||||||
|
badge=lambda obj: obj.journal_entries.count(),
|
||||||
|
permission='extras.view_journalentry'
|
||||||
|
)
|
||||||
|
|
||||||
def get(self, request, model, **kwargs):
|
def get(self, request, model, **kwargs):
|
||||||
|
|
||||||
|
@ -22,14 +22,17 @@ def get_model_urls(app_label, model_name):
|
|||||||
# No views have been registered for this model
|
# No views have been registered for this model
|
||||||
views = []
|
views = []
|
||||||
|
|
||||||
for view in views:
|
for config in views:
|
||||||
# Import the view class or function
|
# Import the view class or function
|
||||||
callable = import_string(view['path'])
|
if type(config['view']) is str:
|
||||||
if issubclass(callable, View):
|
view_ = import_string(config['view'])
|
||||||
callable = callable.as_view()
|
else:
|
||||||
|
view_ = config['view']
|
||||||
|
if issubclass(view_, View):
|
||||||
|
view_ = view_.as_view()
|
||||||
# Create a path to the view
|
# Create a path to the view
|
||||||
paths.append(
|
paths.append(
|
||||||
path(f"{view['name']}/", callable, name=f"{model_name}_{view['name']}", kwargs=view['kwargs'])
|
path(f"{config['name']}/", view_, name=f"{model_name}_{config['name']}", kwargs=config['kwargs'])
|
||||||
)
|
)
|
||||||
|
|
||||||
return paths
|
return paths
|
||||||
|
@ -10,6 +10,7 @@ __all__ = (
|
|||||||
'ContentTypePermissionRequiredMixin',
|
'ContentTypePermissionRequiredMixin',
|
||||||
'GetReturnURLMixin',
|
'GetReturnURLMixin',
|
||||||
'ObjectPermissionRequiredMixin',
|
'ObjectPermissionRequiredMixin',
|
||||||
|
'ViewTab',
|
||||||
'register_model_view',
|
'register_model_view',
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -132,18 +133,23 @@ class GetReturnURLMixin:
|
|||||||
return reverse('home')
|
return reverse('home')
|
||||||
|
|
||||||
|
|
||||||
def register_model_view(model, name, view_path, tab_label=None, tab_badge=None, tab_permission=None, kwargs=None):
|
class ViewTab:
|
||||||
|
|
||||||
|
def __init__(self, label, badge=None, permission=None, always_display=True):
|
||||||
|
self.label = label
|
||||||
|
self.badge = badge
|
||||||
|
self.permission = permission
|
||||||
|
self.always_display = always_display
|
||||||
|
|
||||||
|
|
||||||
|
def register_model_view(model, name, view, kwargs=None):
|
||||||
"""
|
"""
|
||||||
Register a subview for a core model.
|
Register a subview for a core model.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
model: The Django model class with which this view will be associated
|
model: The Django model class with which this view will be associated
|
||||||
name: The name to register when creating a URL path
|
name: The name to register when creating a URL path
|
||||||
view_path: A dotted path to the view class or function (e.g. 'myplugin.views.FooView')
|
view: A class-based or function view, or the dotted path to it (e.g. 'myplugin.views.FooView')
|
||||||
tab_label: The label to display for the view's tab under the model view (optional)
|
|
||||||
tab_badge: A static value or callable to display a badge within the view's tab (optional). If a callable is
|
|
||||||
specified, it must accept the current object as its single positional argument.
|
|
||||||
tab_permission: The name of the permission required to display the tab (optional)
|
|
||||||
kwargs: A dictionary of keyword arguments to send to the view (optional)
|
kwargs: A dictionary of keyword arguments to send to the view (optional)
|
||||||
"""
|
"""
|
||||||
app_label = model._meta.app_label
|
app_label = model._meta.app_label
|
||||||
@ -154,9 +160,6 @@ def register_model_view(model, name, view_path, tab_label=None, tab_badge=None,
|
|||||||
|
|
||||||
registry['views'][app_label][model_name].append({
|
registry['views'][app_label][model_name].append({
|
||||||
'name': name,
|
'name': name,
|
||||||
'path': view_path,
|
'view': view,
|
||||||
'tab_label': tab_label,
|
|
||||||
'tab_badge': tab_badge,
|
|
||||||
'tab_permission': tab_permission,
|
|
||||||
'kwargs': kwargs or {},
|
'kwargs': kwargs or {},
|
||||||
})
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user