Просмотр исходного кода

Merge branch 'feature' into 20925-comments-oranizationalmodel

bctiemann 2 месяцев назад
Родитель
Сommit
834da4e6cd

+ 8 - 0
docs/plugins/development/filtersets.md

@@ -32,6 +32,14 @@ class MyFilterSet(NetBoxModelFilterSet):
         fields = ('some', 'other', 'fields')
 ```
 
+In addition to the base NetBoxModelFilterSet class, the following filterset classes are also available for subclasses of standard base models.
+
+| Model Class           | FilterSet Class                                  |
+|-----------------------|--------------------------------------------------|
+| `PrimaryModel`        | `netbox.filtersets.PrimaryModelFilterSet`        |
+| `OrganizationalModel` | `netbox.filtersets.OrganizationalModelFilterSet` |
+| `NestedGroupModel`    | `netbox.filtersets.NestedGroupModelFilterSet`    |
+
 ### Declaring Filter Sets
 
 To utilize a filter set in a subclass of one of NetBox's generic views (such as `ObjectListView` or `BulkEditView`), define the `filterset` attribute on the view class:

+ 46 - 6
docs/plugins/development/forms.md

@@ -2,7 +2,7 @@
 
 ## Form Classes
 
-NetBox provides several base form classes for use by plugins.
+NetBox provides several base form classes for use by plugins. Additional form classes are also available for other standard base model classes (PrimaryModel, OrganizationalModel, and NestedGroupModel).
 
 | Form Class                 | Purpose                              |
 |----------------------------|--------------------------------------|
@@ -19,7 +19,17 @@ This is the base form for creating and editing NetBox models. It extends Django'
 |-------------|---------------------------------------------------------------------------------------|
 | `fieldsets` | A tuple of `FieldSet` instances which control how form fields are rendered (optional) |
 
-**Example**
+#### Subclasses
+
+The corresponding model-specific subclasses of `NetBoxModelForm` are documented below.
+
+| Model Class           | Form Class                |
+|-----------------------|---------------------------|
+| `PrimaryModel`        | `PrimaryModelForm`        |
+| `OrganizationalModel` | `OrganizationalModelForm` |
+| `NestedGroupModel`    | `NestedGroupModelForm`    |
+
+#### Example
 
 ```python
 from django.utils.translation import gettext_lazy as _
@@ -49,9 +59,19 @@ class MyModelForm(NetBoxModelForm):
 
 ### `NetBoxModelImportForm`
 
-This form facilitates the bulk import of new objects from CSV, JSON, or YAML data. As with model forms, you'll need to declare a `Meta` subclass specifying the associated `model` and `fields`. NetBox also provides several form fields suitable for import various types of CSV data, listed below.
+This form facilitates the bulk import of new objects from CSV, JSON, or YAML data. As with model forms, you'll need to declare a `Meta` subclass specifying the associated `model` and `fields`. NetBox also provides several form fields suitable for importing various types of CSV data, listed [below](#csv-import-fields).
+
+#### Subclasses
+
+The corresponding model-specific subclasses of `NetBoxModelImportForm` are documented below.
+
+| Model Class           | Form Class                      |
+|-----------------------|---------------------------------|
+| `PrimaryModel`        | `PrimaryModelImportForm`        |
+| `OrganizationalModel` | `OrganizationalModelImportForm` |
+| `NestedGroupModel`    | `NestedGroupModelImportForm`    |
 
-**Example**
+#### Example
 
 ```python
 from django.utils.translation import gettext_lazy as _
@@ -83,7 +103,17 @@ This form facilitates editing multiple objects in bulk. Unlike a model form, thi
 | `fieldsets`       | A tuple of `FieldSet` instances which control how form fields are rendered (optional)       |
 | `nullable_fields` | A tuple of fields which can be nullified (set to empty) using the bulk edit form (optional) |
 
-**Example**
+#### Subclasses
+
+The corresponding model-specific subclasses of `NetBoxModelBulkEditForm` are documented below.
+
+| Model Class           | Form Class                        |
+|-----------------------|-----------------------------------|
+| `PrimaryModel`        | `PrimaryModelBulkEditForm`        |
+| `OrganizationalModel` | `OrganizationalModelBulkEditForm` |
+| `NestedGroupModel`    | `NestedGroupModelBulkEditForm`    |
+
+#### Example
 
 ```python
 from django import forms
@@ -125,7 +155,17 @@ This form class is used to render a form expressly for filtering a list of objec
 | `model`     | The model of object being edited                                                      |
 | `fieldsets` | A tuple of `FieldSet` instances which control how form fields are rendered (optional) |
 
-**Example**
+#### Subclasses
+
+The corresponding model-specific subclasses of `NetBoxModelFilterSetForm` are documented below.
+
+| Model Class           | Form Class                         |
+|-----------------------|------------------------------------|
+| `PrimaryModel`        | `PrimaryModelFilterSetForm`        |
+| `OrganizationalModel` | `OrganizationalModelFilterSetForm` |
+| `NestedGroupModel`    | `NestedGroupModelFilterSetForm`    |
+
+#### Example
 
 ```python
 from dcim.models import Site

+ 16 - 0
docs/plugins/development/graphql-api.md

@@ -46,3 +46,19 @@ NetBox provides two object type classes for use by plugins.
 ::: netbox.graphql.types.NetBoxObjectType
     options:
       members: false
+
+## GraphQL Filters
+
+NetBox provides a base filter class for use by plugins which employ subclasseses of `NetBoxModel`.
+
+::: netbox.graphql.filters.NetBoxModelFilter
+    options:
+      members: false
+
+Additionally, the following filter classes are available for subclasses of standard base models.
+
+| Model Class           | FilterSet Class                                    |
+|-----------------------|----------------------------------------------------|
+| `PrimaryModel`        | `netbox.graphql.filters.PrimaryModelFilter`        |
+| `OrganizationalModel` | `netbox.graphql.filters.OrganizationalModelFilter` |
+| `NestedGroupModel`    | `netbox.graphql.filters.NestedGroupModelFilter`    |

+ 40 - 0
docs/plugins/development/models.md

@@ -67,6 +67,46 @@ class MyModel(ExportTemplatesMixin, TagsMixin, models.Model):
     ...
 ```
 
+### Additional Models
+
+In addition to the base NetBoxModel class, the following additional classes are provided for convenience.
+
+!!! info "These model classes were added to the plugins API in NetBox v4.5."
+
+#### PrimaryModel
+
+PrimaryModel is the go-to class for most object types. It extends NetBoxModel with `description` and `comments` fields, and it introduces support for ownership assignment.
+
+| Field         | Required | Unique | Description                                 |
+|---------------|----------|--------|---------------------------------------------|
+| `owner`       | No       | No     | The object's owner                          |
+| `description` | No       | No     | A human-friendly description for the object |
+| `comments`    | No       | No     | General comments                            |
+
+#### OrganizationalModel
+
+OrganizationalModel is used by object types whose function is primarily the organization of other objects.
+
+| Field         | Required | Unique | Description                                 |
+|---------------|----------|--------|---------------------------------------------|
+| `name`        | Yes      | Yes    | The name of the object                      |
+| `slug`        | Yes      | Yes    | A unique URL-friendly identifier            |
+| `owner`       | No       | No     | The object's owner                          |
+| `description` | No       | No     | A human-friendly description for the object |
+
+#### NestedGroupModel
+
+NestedGroupModel is used for objects which arrange into a recursive hierarchy (like regions and locations) via its self-referential `parent` foreign key.
+
+| Field         | Required | Unique | Description                                                     |
+|---------------|----------|--------|-----------------------------------------------------------------|
+| `name`        | Yes      | Yes    | The name of the object                                          |
+| `slug`        | Yes      | Yes    | A unique URL-friendly identifier                                |
+| `parent`      | No       | No     | The object (of the same type) under which this object is nested |
+| `owner`       | No       | No     | The object's owner                                              |
+| `description` | No       | No     | A human-friendly description for the object                     |
+| `comments`    | No       | No     | General comments                                                |
+
 ## Database Migrations
 
 Once you have completed defining the model(s) for your plugin, you'll need to create the database schema migrations. A migration file is essentially a set of instructions for manipulating the PostgreSQL database to support your new model, or to alter existing models. Creating migrations can usually be done automatically using Django's `makemigrations` management command. (Ensure that your plugin has been installed and enabled first, otherwise it won't be found.)

+ 8 - 0
docs/plugins/development/rest-api.md

@@ -27,6 +27,14 @@ Serializers are responsible for converting Python objects to JSON data suitable
 
 The default nested representation of an object is defined by the `brief_fields` attributes under the serializer's `Meta` class. (Older versions of NetBox required the definition of a separate nested serializer.)
 
+In addition to the base NetBoxModelSerializer class, the following serializer classes are also available for subclasses of standard base models.
+
+| Model Class           | Serializer Class                                       |
+|-----------------------|--------------------------------------------------------|
+| `PrimaryModel`        | `netbox.api.serializers.PrimaryModelSerializer`        |
+| `OrganizationalModel` | `netbox.api.serializers.OrganizationalModelSerializer` |
+| `NestedGroupModel`    | `netbox.api.serializers.NestedGroupModelSerializer`    |
+
 #### Example
 
 To create a serializer for a plugin model, subclass `NetBoxModelSerializer` in `api/serializers.py`. Specify the model class and the fields to include within the serializer's `Meta` class.

+ 8 - 0
docs/plugins/development/tables.md

@@ -36,6 +36,14 @@ class MyModelTable(NetBoxTable):
         default_columns = ('pk', 'name', ...)
 ```
 
+In addition to the base NetBoxTable class, the following table classes are also available for subclasses of standard base models.
+
+| Model Class           | Table Class                              |
+|-----------------------|------------------------------------------|
+| `PrimaryModel`        | `netbox.tables.PrimaryModelTable`        |
+| `OrganizationalModel` | `netbox.tables.OrganizationalModelTable` |
+| `NestedGroupModel`    | `netbox.tables.NestedGroupModelTable`    |
+
 ### Table Configuration
 
 The NetBoxTable class features dynamic configuration to allow users to change their column display and ordering preferences. To configure a table for a specific request, simply call its `configure()` method and pass the current HTTPRequest object. For example:

+ 3 - 2
netbox/dcim/api/serializers_/manufacturers.py

@@ -11,13 +11,14 @@ class ManufacturerSerializer(OrganizationalModelSerializer):
 
     # Related object counts
     devicetype_count = RelatedObjectCountField('device_types')
+    moduletype_count = RelatedObjectCountField('module_types')
     inventoryitem_count = RelatedObjectCountField('inventory_items')
     platform_count = RelatedObjectCountField('platforms')
 
     class Meta:
         model = Manufacturer
         fields = [
-            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags',
-            'custom_fields', 'created', 'last_updated', 'devicetype_count', 'inventoryitem_count', 'platform_count',
+            'id', 'url', 'display_url', 'display', 'name', 'slug', 'description', 'owner', 'comments', 'tags', 'custom_fields',
+            'created', 'last_updated', 'devicetype_count', 'moduletype_count', 'inventoryitem_count', 'platform_count',
         ]
         brief_fields = ('id', 'url', 'display', 'name', 'slug', 'description', 'devicetype_count')

+ 12 - 16
netbox/netbox/forms/filtersets.py

@@ -45,10 +45,7 @@ class NetBoxModelFilterSetForm(FilterModifierMixin, CustomFieldsMixin, SavedFilt
         return customfield.to_form_field(set_initial=False, enforce_required=False, enforce_visibility=False)
 
 
-class PrimaryModelFilterSetForm(NetBoxModelFilterSetForm):
-    """
-    FilterSet form for models which inherit from PrimaryModel.
-    """
+class OwnerFilterMixin(forms.Form):
     owner_id = DynamicModelChoiceField(
         queryset=Owner.objects.all(),
         required=False,
@@ -56,23 +53,22 @@ class PrimaryModelFilterSetForm(NetBoxModelFilterSetForm):
     )
 
 
-class OrganizationalModelFilterSetForm(NetBoxModelFilterSetForm):
+class PrimaryModelFilterSetForm(OwnerFilterMixin, NetBoxModelFilterSetForm):
+    """
+    FilterSet form for models which inherit from PrimaryModel.
+    """
+    pass
+
+
+class OrganizationalModelFilterSetForm(OwnerFilterMixin, NetBoxModelFilterSetForm):
     """
     FilterSet form for models which inherit from OrganizationalModel.
     """
-    owner_id = DynamicModelChoiceField(
-        queryset=Owner.objects.all(),
-        required=False,
-        label=_('Owner'),
-    )
+    pass
 
 
-class NestedGroupModelFilterSetForm(NetBoxModelFilterSetForm):
+class NestedGroupModelFilterSetForm(OwnerFilterMixin, NetBoxModelFilterSetForm):
     """
     FilterSet form for models which inherit from NestedGroupModel.
     """
-    owner_id = DynamicModelChoiceField(
-        queryset=Owner.objects.all(),
-        required=False,
-        label=_('Owner'),
-    )
+    pass