mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 09:16:10 -06:00
Add tagging support for ConfigTemplate
This commit is contained in:
parent
3d5b16b677
commit
f92e39b2c9
@ -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',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -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):
|
||||||
|
@ -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',)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -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',),
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
@ -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',
|
||||||
|
@ -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">
|
||||||
|
Loading…
Reference in New Issue
Block a user