From 1461be20041b520b98166cf3129f94ab45acbe0f Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 May 2020 10:28:48 -0400 Subject: [PATCH] Fixes #4613: Fix tag assignment on config contexts (regression from #4527) --- docs/release-notes/version-2.8.md | 1 + netbox/circuits/forms.py | 2 +- netbox/dcim/forms.py | 3 +-- netbox/extras/forms.py | 11 ++++++++++- netbox/ipam/forms.py | 2 +- netbox/project-static/js/forms.js | 16 ++++++++-------- netbox/secrets/forms.py | 2 +- netbox/tenancy/forms.py | 2 +- netbox/virtualization/forms.py | 2 +- 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/docs/release-notes/version-2.8.md b/docs/release-notes/version-2.8.md index e15df481d..7cc05a9f7 100644 --- a/docs/release-notes/version-2.8.md +++ b/docs/release-notes/version-2.8.md @@ -11,6 +11,7 @@ v2.8.4 (FUTURE) * [#4598](https://github.com/netbox-community/netbox/issues/4598) - Display error message when invalid cable length is specified * [#4604](https://github.com/netbox-community/netbox/issues/4604) - Multi-position rear ports may only be connected to other rear ports * [#4607](https://github.com/netbox-community/netbox/issues/4607) - Missing Contextual help for API Tokens +* [#4613](https://github.com/netbox-community/netbox/issues/4613) - Fix tag assignment on config contexts (regression from #4527) * [#4633](https://github.com/netbox-community/netbox/issues/4633) - Bump django-rq to v2.3.2 to fix ImportError with rq 1.4.0 --- diff --git a/netbox/circuits/forms.py b/netbox/circuits/forms.py index 427dc2e89..2185d1eab 100644 --- a/netbox/circuits/forms.py +++ b/netbox/circuits/forms.py @@ -1,9 +1,9 @@ from django import forms -from taggit.forms import TagField from dcim.models import Region, Site from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelForm, CustomFieldModelCSVForm, + TagField, ) from tenancy.forms import TenancyFilterForm, TenancyForm from tenancy.models import Tenant diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 2116d0948..5d3ec1019 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -9,13 +9,12 @@ from django.utils.safestring import mark_safe from mptt.forms import TreeNodeChoiceField from netaddr import EUI from netaddr.core import AddrFormatError -from taggit.forms import TagField from timezone_field import TimeZoneFormField from circuits.models import Circuit, Provider from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldModelCSVForm, CustomFieldFilterForm, CustomFieldModelForm, - LocalConfigContextFilterForm, + LocalConfigContextFilterForm, TagField, ) from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN from ipam.models import IPAddress, VLAN diff --git a/netbox/extras/forms.py b/netbox/extras/forms.py index 384b3563b..469b55efd 100644 --- a/netbox/extras/forms.py +++ b/netbox/extras/forms.py @@ -2,7 +2,7 @@ from django import forms from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType from mptt.forms import TreeNodeMultipleChoiceField -from taggit.forms import TagField +from taggit.forms import TagField as TagField_ from dcim.models import DeviceRole, Platform, Region, Site from tenancy.models import Tenant, TenantGroup @@ -142,6 +142,15 @@ class CustomFieldFilterForm(forms.Form): # Tags # +class TagField(TagField_): + + def widget_attrs(self, widget): + # Apply the "tagfield" CSS class to trigger the special API-based selection widget for tags + return { + 'class': 'tagfield' + } + + class TagForm(BootstrapMixin, forms.ModelForm): slug = SlugField() diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 4e5a413dc..f5fd6e5f8 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -1,10 +1,10 @@ from django import forms from django.core.validators import MaxValueValidator, MinValueValidator -from taggit.forms import TagField from dcim.models import Device, Interface, Rack, Region, Site from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldModelCSVForm, CustomFieldModelForm, CustomFieldFilterForm, + TagField, ) from tenancy.forms import TenancyFilterForm, TenancyForm from tenancy.models import Tenant diff --git a/netbox/project-static/js/forms.js b/netbox/project-static/js/forms.js index 06d4a742a..b97981f0e 100644 --- a/netbox/project-static/js/forms.js +++ b/netbox/project-static/js/forms.js @@ -292,9 +292,9 @@ $(document).ready(function() { }); // API backed tags - var tags = $('#id_tags'); + var tags = $('#id_tags.tagfield'); if (tags.length > 0 && tags.val().length > 0){ - tags = $('#id_tags').val().split(/,\s*/); + tags = $('#id_tags.tagfield').val().split(/,\s*/); } else { tags = []; } @@ -306,8 +306,8 @@ $(document).ready(function() { } }); // Replace the django issued text input with a select element - $('#id_tags').replaceWith(''); - $('#id_tags').select2({ + $('#id_tags.tagfield').replaceWith(''); + $('#id_tags.tagfield').select2({ tags: true, data: tag_objs, multiple: true, @@ -354,14 +354,14 @@ $(document).ready(function() { } } }); - $('#id_tags').closest('form').submit(function(event){ + $('#id_tags.tagfield').closest('form').submit(function(event){ // django-taggit can only accept a single comma seperated string value - var value = $('#id_tags').val(); + var value = $('#id_tags.tagfield').val(); if (value.length > 0){ var final_tags = value.join(', '); - $('#id_tags').val(null).trigger('change'); + $('#id_tags.tagfield').val(null).trigger('change'); var option = new Option(final_tags, final_tags, true, true); - $('#id_tags').append(option).trigger('change'); + $('#id_tags.tagfield').append(option).trigger('change'); } }); diff --git a/netbox/secrets/forms.py b/netbox/secrets/forms.py index 368a47590..089771bd8 100644 --- a/netbox/secrets/forms.py +++ b/netbox/secrets/forms.py @@ -1,11 +1,11 @@ from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA from django import forms -from taggit.forms import TagField from dcim.models import Device from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelForm, CustomFieldModelCSVForm, + TagField, ) from utilities.forms import ( APISelectMultiple, BootstrapMixin, CSVModelChoiceField, CSVModelForm, DynamicModelChoiceField, diff --git a/netbox/tenancy/forms.py b/netbox/tenancy/forms.py index 700d88b1d..bf100f43a 100644 --- a/netbox/tenancy/forms.py +++ b/netbox/tenancy/forms.py @@ -1,8 +1,8 @@ from django import forms -from taggit.forms import TagField from extras.forms import ( AddRemoveTagsForm, CustomFieldModelForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelCSVForm, + TagField, ) from utilities.forms import ( APISelect, APISelectMultiple, BootstrapMixin, CommentField, CSVModelChoiceField, CSVModelForm, diff --git a/netbox/virtualization/forms.py b/netbox/virtualization/forms.py index 0983b2432..2f2ee4950 100644 --- a/netbox/virtualization/forms.py +++ b/netbox/virtualization/forms.py @@ -1,6 +1,5 @@ from django import forms from django.core.exceptions import ValidationError -from taggit.forms import TagField from dcim.choices import InterfaceModeChoices from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN @@ -8,6 +7,7 @@ from dcim.forms import INTERFACE_MODE_HELP_TEXT from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldModelCSVForm, CustomFieldModelForm, CustomFieldFilterForm, + TagField, ) from ipam.models import IPAddress, VLAN from tenancy.forms import TenancyFilterForm, TenancyForm