From 2562c8745c138775eb2f48a5a5af01ee98017895 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Mon, 6 Nov 2023 15:36:59 -0500 Subject: [PATCH] Closes #14156: Add custom field support for contact assignments --- .../tenancy/contactassignment_edit.html | 7 +++++++ netbox/tenancy/api/serializers.py | 2 +- netbox/tenancy/filtersets.py | 5 ++--- netbox/tenancy/forms/model_forms.py | 7 ++----- netbox/tenancy/graphql/types.py | 4 ++-- .../0012_contactassignment_custom_fields.py | 19 +++++++++++++++++++ netbox/tenancy/models/contacts.py | 4 ++-- 7 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 netbox/tenancy/migrations/0012_contactassignment_custom_fields.py diff --git a/netbox/templates/tenancy/contactassignment_edit.html b/netbox/templates/tenancy/contactassignment_edit.html index ef203697689..09a267c0472 100644 --- a/netbox/templates/tenancy/contactassignment_edit.html +++ b/netbox/templates/tenancy/contactassignment_edit.html @@ -25,4 +25,11 @@
{% trans "Contact Assignment" %}
{% render_field form.priority %} {% render_field form.tags %} + +
+
+
{% trans "Custom Fields" %}
+
+ {% render_custom_fields form %} +
{% endblock %} diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py index da0ad04bd2d..118cafd81da 100644 --- a/netbox/tenancy/api/serializers.py +++ b/netbox/tenancy/api/serializers.py @@ -105,7 +105,7 @@ class Meta: model = ContactAssignment fields = [ 'id', 'url', 'display', 'content_type', 'object_id', 'object', 'contact', 'role', 'priority', 'tags', - 'created', 'last_updated', + 'custom_fields', 'created', 'last_updated', ] @extend_schema_field(OpenApiTypes.OBJECT) diff --git a/netbox/tenancy/filtersets.py b/netbox/tenancy/filtersets.py index 0f4900f546f..72f03e98ac7 100644 --- a/netbox/tenancy/filtersets.py +++ b/netbox/tenancy/filtersets.py @@ -3,11 +3,10 @@ from django.utils.translation import gettext as _ from extras.filters import TagFilter -from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet +from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter from .models import * - __all__ = ( 'ContactAssignmentFilterSet', 'ContactFilterSet', @@ -81,7 +80,7 @@ def search(self, queryset, name, value): ) -class ContactAssignmentFilterSet(ChangeLoggedModelFilterSet): +class ContactAssignmentFilterSet(NetBoxModelFilterSet): q = django_filters.CharFilter( method='search', label=_('Search'), diff --git a/netbox/tenancy/forms/model_forms.py b/netbox/tenancy/forms/model_forms.py index 5b1051c68cb..9a53eba1729 100644 --- a/netbox/tenancy/forms/model_forms.py +++ b/netbox/tenancy/forms/model_forms.py @@ -1,12 +1,9 @@ from django import forms from django.utils.translation import gettext_lazy as _ -from extras.forms.mixins import TagsMixin -from extras.models import Tag from netbox.forms import NetBoxModelForm from tenancy.models import * -from utilities.forms.mixins import BootstrapMixin -from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField +from utilities.forms.fields import CommentField, DynamicModelChoiceField, SlugField __all__ = ( 'ContactAssignmentForm', @@ -122,7 +119,7 @@ class Meta: } -class ContactAssignmentForm(BootstrapMixin, TagsMixin, forms.ModelForm): +class ContactAssignmentForm(NetBoxModelForm): group = DynamicModelChoiceField( label=_('Group'), queryset=ContactGroup.objects.all(), diff --git a/netbox/tenancy/graphql/types.py b/netbox/tenancy/graphql/types.py index 727aa2eac9b..aab02b121f5 100644 --- a/netbox/tenancy/graphql/types.py +++ b/netbox/tenancy/graphql/types.py @@ -1,6 +1,6 @@ import graphene -from extras.graphql.mixins import TagsMixin +from extras.graphql.mixins import CustomFieldsMixin, TagsMixin from tenancy import filtersets, models from netbox.graphql.types import BaseObjectType, OrganizationalObjectType, NetBoxObjectType @@ -69,7 +69,7 @@ class Meta: filterset_class = filtersets.ContactGroupFilterSet -class ContactAssignmentType(TagsMixin, BaseObjectType): +class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType): class Meta: model = models.ContactAssignment diff --git a/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py b/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py new file mode 100644 index 00000000000..ee672682236 --- /dev/null +++ b/netbox/tenancy/migrations/0012_contactassignment_custom_fields.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.6 on 2023-11-06 20:23 + +from django.db import migrations, models +import utilities.json + + +class Migration(migrations.Migration): + + dependencies = [ + ('tenancy', '0011_contactassignment_tags'), + ] + + operations = [ + migrations.AddField( + model_name='contactassignment', + name='custom_field_data', + field=models.JSONField(blank=True, default=dict, encoder=utilities.json.CustomFieldJSONEncoder), + ), + ] diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py index e8327248d14..6cc26fa83fe 100644 --- a/netbox/tenancy/models/contacts.py +++ b/netbox/tenancy/models/contacts.py @@ -5,7 +5,7 @@ from django.utils.translation import gettext_lazy as _ from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel -from netbox.models.features import TagsMixin +from netbox.models.features import CustomFieldsMixin, TagsMixin from tenancy.choices import * __all__ = ( @@ -109,7 +109,7 @@ def get_absolute_url(self): return reverse('tenancy:contact', args=[self.pk]) -class ContactAssignment(ChangeLoggedModel, TagsMixin): +class ContactAssignment(CustomFieldsMixin, TagsMixin, ChangeLoggedModel): content_type = models.ForeignKey( to=ContentType, on_delete=models.CASCADE