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