17170 Add ability to add contacts to multiple contact groups (#18885)

* 17170 Allow multiple Group assignments for Contacts

* 17170 update docs

* 17170 update api, detail view, graphql

* 17170 fixes

* 17170 fixes

* 17170 fixes

* 17170 fixes

* 17170 fixes

* 17170 fixes

* 17170 fix bulk import

* 17170 test fixes

* 17170 test fixes

* 17170 test fixes

* 17178 review changes

* 17178 review changes

* 17178 review changes

* 17178 review changes

* 17178 review changes

* 17178 review changes

* 17170 update migration

* 17170 bulk edit form
This commit is contained in:
Arthur Hanson
2025-03-18 11:05:02 -07:00
committed by GitHub
parent d4f8cb72aa
commit af5ec19430
18 changed files with 204 additions and 78 deletions

View File

@@ -5,7 +5,7 @@ from netbox.forms import NetBoxModelBulkEditForm
from tenancy.choices import ContactPriorityChoices
from tenancy.models import *
from utilities.forms import add_blank_choice
from utilities.forms.fields import CommentField, DynamicModelChoiceField
from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField
from utilities.forms.rendering import FieldSet
__all__ = (
@@ -90,8 +90,13 @@ class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
class ContactBulkEditForm(NetBoxModelBulkEditForm):
group = DynamicModelChoiceField(
label=_('Group'),
add_groups = DynamicModelMultipleChoiceField(
label=_('Add groups'),
queryset=ContactGroup.objects.all(),
required=False
)
remove_groups = DynamicModelMultipleChoiceField(
label=_('Remove groups'),
queryset=ContactGroup.objects.all(),
required=False
)
@@ -127,9 +132,13 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
model = Contact
fieldsets = (
FieldSet('group', 'title', 'phone', 'email', 'address', 'link', 'description'),
FieldSet('title', 'phone', 'email', 'address', 'link', 'description'),
FieldSet('add_groups', 'remove_groups', name=_('Groups')),
)
nullable_fields = (
'add_groups', 'remove_groups', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments'
)
nullable_fields = ('group', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments')
class ContactAssignmentBulkEditForm(NetBoxModelBulkEditForm):

View File

@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelImportForm
from tenancy.models import *
from utilities.forms.fields import CSVContentTypeField, CSVModelChoiceField, SlugField
from utilities.forms.fields import CSVContentTypeField, CSVModelChoiceField, CSVModelMultipleChoiceField, SlugField
__all__ = (
'ContactAssignmentImportForm',
@@ -77,17 +77,16 @@ class ContactRoleImportForm(NetBoxModelImportForm):
class ContactImportForm(NetBoxModelImportForm):
group = CSVModelChoiceField(
label=_('Group'),
groups = CSVModelMultipleChoiceField(
queryset=ContactGroup.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned group')
help_text=_('Group names separated by commas, encased with double quotes (e.g. "Group 1,Group 2")')
)
class Meta:
model = Contact
fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'group', 'description', 'comments', 'tags')
fields = ('name', 'title', 'phone', 'email', 'address', 'link', 'groups', 'description', 'comments', 'tags')
class ContactAssignmentImportForm(NetBoxModelImportForm):

View File

@@ -75,7 +75,7 @@ class ContactFilterForm(NetBoxModelFilterSetForm):
queryset=ContactGroup.objects.all(),
required=False,
null_option='None',
label=_('Group')
label=_('Groups')
)
tag = TagFilterField(model)

View File

@@ -3,7 +3,7 @@ from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelForm
from tenancy.models import *
from utilities.forms.fields import CommentField, DynamicModelChoiceField, SlugField
from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField
from utilities.forms.rendering import FieldSet, ObjectAttribute
__all__ = (
@@ -93,8 +93,8 @@ class ContactRoleForm(NetBoxModelForm):
class ContactForm(NetBoxModelForm):
group = DynamicModelChoiceField(
label=_('Group'),
groups = DynamicModelMultipleChoiceField(
label=_('Groups'),
queryset=ContactGroup.objects.all(),
required=False
)
@@ -102,7 +102,7 @@ class ContactForm(NetBoxModelForm):
fieldsets = (
FieldSet(
'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags',
'groups', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags',
name=_('Contact')
),
)
@@ -110,7 +110,7 @@ class ContactForm(NetBoxModelForm):
class Meta:
model = Contact
fields = (
'group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments', 'tags',
'groups', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'comments', 'tags',
)
widgets = {
'address': forms.Textarea(attrs={'rows': 3}),
@@ -123,7 +123,7 @@ class ContactAssignmentForm(NetBoxModelForm):
queryset=ContactGroup.objects.all(),
required=False,
initial_params={
'contacts': '$contact'
'contact': '$contact'
}
)
contact = DynamicModelChoiceField(