Add tagging support for ConfigTemplate

This commit is contained in:
jeremystretch 2023-02-16 14:52:03 -05:00
parent 3d5b16b677
commit f92e39b2c9
9 changed files with 19 additions and 9 deletions

View File

@ -16,6 +16,7 @@ from extras.utils import FeatureQuery
from netbox.api.exceptions import SerializerNotFound from netbox.api.exceptions import SerializerNotFound
from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField from netbox.api.fields import ChoiceField, ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import BaseModelSerializer, NetBoxModelSerializer, ValidatedModelSerializer from netbox.api.serializers import BaseModelSerializer, NetBoxModelSerializer, ValidatedModelSerializer
from netbox.api.serializers.features import TaggableModelSerializer
from netbox.constants import NESTED_SERIALIZER_PREFIX from netbox.constants import NESTED_SERIALIZER_PREFIX
from tenancy.api.nested_serializers import NestedTenantSerializer, NestedTenantGroupSerializer from tenancy.api.nested_serializers import NestedTenantSerializer, NestedTenantGroupSerializer
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
@ -29,6 +30,7 @@ from .nested_serializers import *
__all__ = ( __all__ = (
'ConfigContextSerializer', 'ConfigContextSerializer',
'ConfigTemplateSerializer',
'ContentTypeSerializer', 'ContentTypeSerializer',
'CustomFieldSerializer', 'CustomFieldSerializer',
'CustomLinkSerializer', 'CustomLinkSerializer',
@ -387,7 +389,7 @@ class ConfigContextSerializer(ValidatedModelSerializer):
# Config templates # Config templates
# #
class ConfigTemplateSerializer(ValidatedModelSerializer): class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='extras-api:configtemplate-detail') url = serializers.HyperlinkedIdentityField(view_name='extras-api:configtemplate-detail')
data_source = NestedDataSourceSerializer( data_source = NestedDataSourceSerializer(
required=False required=False
@ -400,7 +402,7 @@ class ConfigTemplateSerializer(ValidatedModelSerializer):
model = ConfigTemplate model = ConfigTemplate
fields = [ fields = [
'id', 'url', 'display', 'name', 'description', 'environment_params', 'template_code', 'data_source', 'id', 'url', 'display', 'name', 'description', 'environment_params', 'template_code', 'data_source',
'data_path', 'data_file', 'data_synced', 'created', 'last_updated', 'data_path', 'data_file', 'data_synced', 'tags', 'created', 'last_updated',
] ]

View File

@ -11,6 +11,7 @@ from tenancy.models import Tenant, TenantGroup
from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
from virtualization.models import Cluster, ClusterGroup, ClusterType from virtualization.models import Cluster, ClusterGroup, ClusterType
from .choices import * from .choices import *
from .filters import TagFilter
from .models import * from .models import *
__all__ = ( __all__ = (
@ -467,6 +468,7 @@ class ConfigTemplateFilterSet(BaseFilterSet):
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
label=_('Data file (ID)'), label=_('Data file (ID)'),
) )
tag = TagFilter()
class Meta: class Meta:
model = ConfigTemplate model = ConfigTemplate

View File

@ -89,7 +89,7 @@ class ConfigTemplateImportForm(CSVModelForm):
class Meta: class Meta:
model = ConfigTemplate model = ConfigTemplate
fields = ( fields = (
'name', 'description', 'environment_params', 'template_code', 'name', 'description', 'environment_params', 'template_code', 'tags',
) )

View File

@ -367,7 +367,7 @@ class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm): class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id', 'tag')),
('Data', ('data_source_id', 'data_file_id')), ('Data', ('data_source_id', 'data_file_id')),
) )
data_source_id = DynamicModelMultipleChoiceField( data_source_id = DynamicModelMultipleChoiceField(
@ -383,6 +383,7 @@ class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm):
'source_id': '$data_source_id' 'source_id': '$data_source_id'
} }
) )
tag = TagFilterField(ConfigTemplate)
class LocalConfigContextFilterForm(forms.Form): class LocalConfigContextFilterForm(forms.Form):

View File

@ -281,7 +281,7 @@ class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
) )
fieldsets = ( fieldsets = (
('Export Template', ('name', 'description', 'environment_params', 'tags')), ('Config Template', ('name', 'description', 'environment_params', 'tags')),
('Content', ('data_source', 'data_file', 'template_code',)), ('Content', ('data_source', 'data_file', 'template_code',)),
) )

View File

@ -1,7 +1,6 @@
# Generated by Django 4.1.6 on 2023-02-09 19:33
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion
import taggit.managers
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -26,6 +25,7 @@ class Migration(migrations.Migration):
('environment_params', models.JSONField(blank=True, null=True)), ('environment_params', models.JSONField(blank=True, null=True)),
('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')), ('data_file', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='core.datafile')),
('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')), ('data_source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='+', to='core.datasource')),
('tags', taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag')),
], ],
options={ options={
'ordering': ('name',), 'ordering': ('name',),

View File

@ -9,7 +9,7 @@ from jinja2.sandbox import SandboxedEnvironment
from extras.querysets import ConfigContextQuerySet from extras.querysets import ConfigContextQuerySet
from netbox.config import get_config from netbox.config import get_config
from netbox.models import ChangeLoggedModel from netbox.models import ChangeLoggedModel
from netbox.models.features import ExportTemplatesMixin, SyncedDataMixin from netbox.models.features import ExportTemplatesMixin, SyncedDataMixin, TagsMixin
from utilities.jinja2 import ConfigTemplateLoader from utilities.jinja2 import ConfigTemplateLoader
from utilities.utils import deepmerge from utilities.utils import deepmerge
@ -193,7 +193,7 @@ class ConfigContextModel(models.Model):
# Config templates # Config templates
# #
class ConfigTemplate(SyncedDataMixin, ExportTemplatesMixin, ChangeLoggedModel): class ConfigTemplate(SyncedDataMixin, ExportTemplatesMixin, TagsMixin, ChangeLoggedModel):
name = models.CharField( name = models.CharField(
max_length=100 max_length=100
) )

View File

@ -237,11 +237,15 @@ class ConfigTemplateTable(NetBoxTable):
is_synced = columns.BooleanColumn( is_synced = columns.BooleanColumn(
verbose_name='Synced' verbose_name='Synced'
) )
tags = columns.TagColumn(
url_name='extras:configtemplate_list'
)
class Meta(NetBoxTable.Meta): class Meta(NetBoxTable.Meta):
model = ConfigTemplate model = ConfigTemplate
fields = ( fields = (
'pk', 'id', 'name', 'description', 'data_source', 'data_file', 'data_synced', 'created', 'last_updated', 'pk', 'id', 'name', 'description', 'data_source', 'data_file', 'data_synced', 'created', 'last_updated',
'tags',
) )
default_columns = ( default_columns = (
'pk', 'name', 'description', 'is_synced', 'pk', 'name', 'description', 'is_synced',

View File

@ -49,6 +49,7 @@
</table> </table>
</div> </div>
</div> </div>
{% include 'inc/panels/tags.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-md-7"> <div class="col col-md-7">