Skip to content

视图

编写视图

如果您的插件将在NetBox Web界面中提供自己的页面或页面,您需要定义视图。视图是一段业务逻辑,当对特定URL发出请求时,它执行操作和/或呈现页面。HTML内容是使用模板呈现的。视图通常在views.py中定义,URL模式在urls.py中定义。

例如,让我们编写一个视图,该视图显示一个随机动物和它发出的声音。我们将使用Django的通用View类来最小化需要的样板代码量。

from django.shortcuts import render
from django.views.generic import View
from .models import Animal

class RandomAnimalView(View):
    """
    Display a randomly-selected animal.
    """
    def get(self, request):
        animal = Animal.objects.order_by('?').first()
        return render(request, 'netbox_animal_sounds/animal.html', {
            'animal': animal,
        })

这个视图从数据库中检索一个随机的Animal实例,并在呈现名为animal.html的模板时将其作为上下文变量传递。HTTP GET请求由视图的get()方法处理,POST请求由其post()方法处理。

我们上面的示例非常简单,但视图可以做几乎任何事情。通常情况下,您的插件的核心功能将驻留在视图中。视图也不仅限于返回HTML内容:视图可以返回CSV文件或图像,例如。有关视图的更多信息,请参阅Django文档

URL注册

要使视图对用户可访问,我们需要在urls.py中注册一个URL。我们通过定义包含路径列表的urlpatterns变量来实现这一点。

from django.urls import path
from . import views

urlpatterns = [
    path('random/', views.RandomAnimalView.as_view(), name='random_animal'),
]

URL模式有三个组成部分:

  • route - 专用于此视图的唯一URL部分
  • view - 视图本身
  • name - 用于在内部识别URL路径的短名称

这使我们的视图可在URL /plugins/animal-sounds/random/上访问。 (请记住,我们的AnimalSoundsConfig类将插件的基本URL设置为animal-sounds。)访问此URL应该显示具有我们自定义内容的基本NetBox模板。

视图类

NetBox提供了几个通用视图类(下面的文档中有详细说明),用于执行常见操作,例如创建、查看、修改和删除对象。插件可以子类化这些视图以供其自己使用。

视图类 描述
ObjectView 查看单个对象
ObjectEditView 创建或编辑单个对象
ObjectDeleteView 删除单个对象
ObjectChildrenView 父对象上下文中的子对象列表
ObjectListView 查看对象列表
BulkImportView 导入一组新对象
BulkEditView 同时编辑多个对象
BulkDeleteView 同时删除多个对象

Warning

请注意,目前仅支持此文档中出现的类。虽然views.generic模块中可能存在其他类,但它们尚不支持供插件使用。

示例用法

# views.py
from netbox.views.generic import ObjectEditView
from .models import Thing

class ThingEditView(ObjectEditView):
    queryset = Thing.objects.all()
    template_name = 'myplugin/thing.html'
    ...

对象视图

以下是NetBox对象视图的类定义。这些视图处理单个对象的CRUD操作。视图、添加/编辑和删除视图都继承自BaseObjectView,不打算直接使用它。

BaseObjectView (ObjectPermissionRequiredMixin, View)

Base class for generic views which display or manipulate a single object.

Attributes:

Name Type Description
queryset

Django QuerySet from which the object(s) will be fetched

template_name

The name of the HTML template file to render

get_queryset(self, request)

Return the base queryset for the view. By default, this returns self.queryset.all().

Parameters:

Name Type Description Default
request

The current request

required

get_object(self, **kwargs)

Return the object being viewed or modified. The object is identified by an arbitrary set of keyword arguments gleaned from the URL, which are passed to get_object_or_404(). (Typically, only a primary key is needed.)

If no matching object is found, return a 404 response.

get_extra_context(self, request, instance)

Return any additional context data to include when rendering the template.

Parameters:

Name Type Description Default
request

The current request

required
instance

The object being viewed

required

ObjectView (BaseObjectView)

Retrieve a single object for display.

Note: If template_name is not specified, it will be determined automatically based on the queryset model.

Attributes:

Name Type Description
tab

A ViewTab instance for the view

get_template_name(self)

Return self.template_name if defined. Otherwise, dynamically resolve the template name using the queryset model's app_label and model_name.

ObjectEditView (GetReturnURLMixin, BaseObjectView)

Create or edit a single object.

Attributes:

Name Type Description
form

The form used to create or edit the object

alter_object(self, obj, request, url_args, url_kwargs)

Provides a hook for views to modify an object before it is processed. For example, a parent object can be defined given some parameter from the request URL.

Parameters:

Name Type Description Default
obj

The object being edited

required
request

The current request

required
url_args

URL path args

required
url_kwargs

URL path kwargs

required

ObjectDeleteView (GetReturnURLMixin, BaseObjectView)

Delete a single object.

ObjectChildrenView (ObjectView, ActionsMixin, TableMixin)

Display a table of child objects associated with the parent object. For example, NetBox uses this to display the set of child IP addresses within a parent prefix.

Attributes:

Name Type Description
child_model

The model class which represents the child objects

table

The django-tables2 Table class used to render the child objects list

filterset

A django-filter FilterSet that is applied to the queryset

actions

A mapping of supported actions to their required permissions. When adding custom actions, bulk action names must be prefixed with bulk_. (See ActionsMixin.)

get_children(self, request, parent)

Return a QuerySet of child objects.

Parameters:

Name Type Description Default
request

The current request

required
parent

The parent object

required

prep_table_data(self, request, queryset, parent)

Provides a hook for subclassed views to modify data before initializing the table.

Parameters:

Name Type Description Default
request

The current request

required
queryset

The filtered queryset of child objects

required
parent

The parent object

required

多对象视图

以下是NetBox的多对象视图的类定义。这些视图处理一组对象的同时操作。列表、导入、编辑和删除视图都继承自BaseMultiObjectView,不打算直接使用它。

BaseMultiObjectView (ObjectPermissionRequiredMixin, View)

Base class for generic views which display or manipulate multiple objects.

Attributes:

Name Type Description
queryset

Django QuerySet from which the object(s) will be fetched

table

The django-tables2 Table class used to render the objects list

template_name

The name of the HTML template file to render

get_queryset(self, request)

Return the base queryset for the view. By default, this returns self.queryset.all().

Parameters:

Name Type Description Default
request

The current request

required

get_extra_context(self, request)

Return any additional context data to include when rendering the template.

Parameters:

Name Type Description Default
request

The current request

required

ObjectListView (BaseMultiObjectView, ActionsMixin, TableMixin)

Display multiple objects, all the same type, as a table.

Attributes:

Name Type Description
filterset

A django-filter FilterSet that is applied to the queryset

filterset_form

The form class used to render filter options

actions

A mapping of supported actions to their required permissions. When adding custom actions, bulk action names must be prefixed with bulk_. (See ActionsMixin.)

export_table(self, table, columns=None, filename=None)

Export all table data in CSV format.

Parameters:

Name Type Description Default
table

The Table instance to export

required
columns

A list of specific columns to include. If None, all columns will be exported.

None
filename

The name of the file attachment sent to the client. If None, will be determined automatically from the queryset model name.

None

export_template(self, template, request)

Render an ExportTemplate using the current queryset.

Parameters:

Name Type Description Default
template

ExportTemplate instance

required
request

The current request

required

BulkImportView (GetReturnURLMixin, BaseMultiObjectView)

Import objects in bulk (CSV format).

Attributes:

Name Type Description
model_form

The form used to create each imported object

save_object(self, object_form, request)

Provide a hook to modify the object immediately before saving it (e.g. to encrypt secret data).

Parameters:

Name Type Description Default
object_form

The model form instance

required
request

The current request

required

BulkEditView (GetReturnURLMixin, BaseMultiObjectView)

Edit objects in bulk.

Attributes:

Name Type Description
filterset

FilterSet to apply when deleting by QuerySet

form

The form class used to edit objects in bulk

BulkDeleteView (GetReturnURLMixin, BaseMultiObjectView)

Delete objects in bulk.

Attributes:

Name Type Description
filterset

FilterSet to apply when deleting by QuerySet

table

The table used to display devices being deleted

get_form(self)

Provide a standard bulk delete form if none has been specified for the view

功能视图

提供这些视图以启用或增强NetBox模型功能,例如更改日志记录或日志记录。通常不需要对其进行子类化:它们可以直接使用,例如在URL路径中使用。

ObjectChangeLogView (View)

Present a history of changes made to a particular object. The model class must be passed as a keyword argument when referencing this view in a URL path. For example:

path('sites/<int:pk>/changelog/', ObjectChangeLogView.as_view(), name='site_changelog', kwargs={'model': Site}),

Attributes:

Name Type Description
base_template

The name of the template to extend. If not provided, "{app}/{model}.html" will be used.

ObjectJournalView (View)

Show all journal entries for an object. The model class must be passed as a keyword argument when referencing this view in a URL path. For example:

path('sites/<int:pk>/journal/', ObjectJournalView.as_view(), name='site_journal', kwargs={'model': Site}),

Attributes:

Name Type Description
base_template

The name of the template to extend. If not provided, "{app}/{model}.html" will be used.

扩展核心视图

额外的选项卡

插件可以通过使用register_model_view()将自定义视图注册到核心NetBox模型中,以将其"附加"到核心NetBox模型。要在NetBox UI中包含此视图的选项卡,请声明一个名为tab的TabView实例:

from dcim.models import Site
from myplugin.models import Stuff
from netbox.views import generic
from utilities.views import ViewTab, register_model_view

@register_model_view(Site, name='myview', path='some-other-stuff')
class MyView(generic.ObjectView):
    ...
    tab = ViewTab(
        label='Other Stuff',
        badge=lambda obj: Stuff.objects.filter(site=obj).count(),
        permission='myplugin.view_stuff'
    )

register_model_view(model, name='', path=None, kwargs=None)

This decorator can be used to "attach" a view to any model in NetBox. This is typically used to inject additional tabs within a model's detail view. For example, to add a custom tab to NetBox's dcim.Site model:

@register_model_view(Site, 'myview', path='my-custom-view')
class MyView(ObjectView):
    ...

This will automatically create a URL path for MyView at /dcim/sites/<id>/my-custom-view/ which can be resolved using the view name `dcim:site_myview'.

Parameters:

Name Type Description Default
model

The Django model class with which this view will be associated.

required
name

The string used to form the view's name for URL resolution (e.g. via reverse()). This will be appended to the name of the base view for the model using an underscore. If blank, the model name will be used.

''
path

The URL path by which the view can be reached (optional). If not provided, name will be used.

None
kwargs

A dictionary of keyword arguments for the view to include when registering its URL path (optional).

None

ViewTab

ViewTabs are used for navigation among multiple object-specific views, such as the changelog or journal for a particular object.

Parameters:

Name Type Description Default
label

Human-friendly text

required
badge

A static value or callable to display alongside the label (optional). If a callable is used, it must accept a single argument representing the object being viewed.

None
weight

Numeric weight to influence ordering among other tabs (default: 1000)

1000
permission

The permission required to display the tab (optional).

None
hide_if_empty

If true, the tab will be displayed only if its badge has a meaningful value. (Tabs without a badge are always displayed.)

False

render(self, instance)

Return the attributes needed to render a tab in HTML.

额外的模板内容

插件可以将自定义内容注入到核心NetBox视图的某些区域。这是通过子类化PluginTemplateExtension、指定特定的NetBox模型,并定义要呈现自定义内容的所需方法来实现的。有五种方法可用:

方法 视图 描述
left_page() 对象视图 注入页面左侧的内容
right_page() 对象视图 注入页面右侧的内容
full_width_page() 对象视图 注入整个页面底部的内容
buttons() 对象视图 在页面顶部添加按钮
list_buttons() 列表视图 在页面顶部添加按钮

此外,还提供了一个render()方法,以方便起见。此方法接受要呈现的模板名称以及要传递的任何其他上下文数据。它的使用是可选的。

当实例化PluginTemplateExtension时,上下文数据分配给self.context。可用数据包括:

  • object - 正在查看的对象(仅限对象视图)
  • model - 列表视图的模型(仅限列表视图)
  • request - 当前请求
  • settings - 全局NetBox设置
  • config - 插件特定的配置参数

例如,在模板中访问{{ request.user }}将返回当前用户。

声明的子类应该被收集到一个列表或元组中,以与NetBox集成。默认情况下,NetBox在template_content.py文件中查找名为template_extensions的可迭代对象。 (这可以通过在插件的PluginConfig上设置template_extensions为自定义值来覆盖。)以下是一个示例。

from netbox.plugins import PluginTemplateExtension
from .models import Animal

class SiteAnimalCount(PluginTemplateExtension):
    model = 'dcim.site'

    def right_page(self):
        return self.render('netbox_animal_sounds/inc/animal_count.html', extra_context={
            'animal_count': Animal.objects.count(),
        })

template_extensions = [SiteAnimalCount]