From 353c2a5f15c8575454dd7fa4908cf8dc07474193 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Sat, 8 Jul 2023 12:52:29 +0530 Subject: [PATCH] adds tags on contact assignments #12882 --- .../tenancy/contactassignment_edit.html | 1 + netbox/tenancy/api/serializers.py | 4 ++-- netbox/tenancy/filtersets.py | 4 +++- netbox/tenancy/forms/filtersets.py | 1 + netbox/tenancy/forms/model_forms.py | 9 +++++++-- .../migrations/0011_contactassignment_tags.py | 20 +++++++++++++++++++ netbox/tenancy/models/contacts.py | 3 ++- netbox/tenancy/tables/contacts.py | 5 ++++- 8 files changed, 40 insertions(+), 7 deletions(-) create mode 100644 netbox/tenancy/migrations/0011_contactassignment_tags.py diff --git a/netbox/templates/tenancy/contactassignment_edit.html b/netbox/templates/tenancy/contactassignment_edit.html index d904deead..1d494a7d1 100644 --- a/netbox/templates/tenancy/contactassignment_edit.html +++ b/netbox/templates/tenancy/contactassignment_edit.html @@ -22,5 +22,6 @@ {% render_field form.contact %} {% render_field form.role %} {% render_field form.priority %} + {% render_field form.tags %} {% endblock %} diff --git a/netbox/tenancy/api/serializers.py b/netbox/tenancy/api/serializers.py index 75d68a4a5..da0ad04bd 100644 --- a/netbox/tenancy/api/serializers.py +++ b/netbox/tenancy/api/serializers.py @@ -104,8 +104,8 @@ class ContactAssignmentSerializer(NetBoxModelSerializer): class Meta: model = ContactAssignment fields = [ - 'id', 'url', 'display', 'content_type', 'object_id', 'object', 'contact', 'role', 'priority', 'created', - 'last_updated', + 'id', 'url', 'display', 'content_type', 'object_id', 'object', 'contact', 'role', 'priority', 'tags', + 'created', 'last_updated', ] @extend_schema_field(OpenApiTypes.OBJECT) diff --git a/netbox/tenancy/filtersets.py b/netbox/tenancy/filtersets.py index 1edc8fdc8..0f4900f54 100644 --- a/netbox/tenancy/filtersets.py +++ b/netbox/tenancy/filtersets.py @@ -2,6 +2,7 @@ import django_filters from django.db.models import Q from django.utils.translation import gettext as _ +from extras.filters import TagFilter from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter from .models import * @@ -100,10 +101,11 @@ class ContactAssignmentFilterSet(ChangeLoggedModelFilterSet): to_field_name='slug', label=_('Contact role (slug)'), ) + tag = TagFilter() class Meta: model = ContactAssignment - fields = ['id', 'content_type_id', 'object_id', 'priority'] + fields = ['id', 'content_type_id', 'object_id', 'priority', 'tag'] def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/tenancy/forms/filtersets.py b/netbox/tenancy/forms/filtersets.py index 626d26785..fc4f59f43 100644 --- a/netbox/tenancy/forms/filtersets.py +++ b/netbox/tenancy/forms/filtersets.py @@ -111,3 +111,4 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm): choices=ContactPriorityChoices, required=False ) + tag = TagFilterField(model) diff --git a/netbox/tenancy/forms/model_forms.py b/netbox/tenancy/forms/model_forms.py index 6d6534d40..2d58e442d 100644 --- a/netbox/tenancy/forms/model_forms.py +++ b/netbox/tenancy/forms/model_forms.py @@ -1,9 +1,10 @@ from django import forms +from extras.models import Tag from netbox.forms import NetBoxModelForm from tenancy.models import * from utilities.forms import BootstrapMixin -from utilities.forms.fields import CommentField, DynamicModelChoiceField, SlugField +from utilities.forms.fields import CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField __all__ = ( 'ContactAssignmentForm', @@ -132,11 +133,15 @@ class ContactAssignmentForm(BootstrapMixin, forms.ModelForm): role = DynamicModelChoiceField( queryset=ContactRole.objects.all() ) + tags = DynamicModelMultipleChoiceField( + queryset=Tag.objects.all(), + required=False + ) class Meta: model = ContactAssignment fields = ( - 'content_type', 'object_id', 'group', 'contact', 'role', 'priority', + 'content_type', 'object_id', 'group', 'contact', 'role', 'priority', 'tags' ) widgets = { 'content_type': forms.HiddenInput(), diff --git a/netbox/tenancy/migrations/0011_contactassignment_tags.py b/netbox/tenancy/migrations/0011_contactassignment_tags.py new file mode 100644 index 000000000..8eb813af2 --- /dev/null +++ b/netbox/tenancy/migrations/0011_contactassignment_tags.py @@ -0,0 +1,20 @@ +# Generated by Django 4.1.10 on 2023-07-08 07:17 + +from django.db import migrations +import taggit.managers + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0092_delete_jobresult'), + ('tenancy', '0010_tenant_relax_uniqueness'), + ] + + operations = [ + migrations.AddField( + model_name='contactassignment', + name='tags', + field=taggit.managers.TaggableManager(through='extras.TaggedItem', to='extras.Tag'), + ), + ] diff --git a/netbox/tenancy/models/contacts.py b/netbox/tenancy/models/contacts.py index 1df5e3305..046f06fc6 100644 --- a/netbox/tenancy/models/contacts.py +++ b/netbox/tenancy/models/contacts.py @@ -4,6 +4,7 @@ from django.db import models from django.urls import reverse from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel +from netbox.models.features import TagsMixin from tenancy.choices import * __all__ = ( @@ -92,7 +93,7 @@ class Contact(PrimaryModel): return reverse('tenancy:contact', args=[self.pk]) -class ContactAssignment(ChangeLoggedModel): +class ContactAssignment(ChangeLoggedModel, TagsMixin): content_type = models.ForeignKey( to=ContentType, on_delete=models.CASCADE diff --git a/netbox/tenancy/tables/contacts.py b/netbox/tenancy/tables/contacts.py index 7de8ffceb..24d695bda 100644 --- a/netbox/tenancy/tables/contacts.py +++ b/netbox/tenancy/tables/contacts.py @@ -115,6 +115,9 @@ class ContactAssignmentTable(NetBoxTable): accessor=Accessor('contact__description'), verbose_name='Contact Description' ) + tags = columns.TagColumn( + url_name='tenancy:contactassignment_list' + ) actions = columns.ActionsColumn( actions=('edit', 'delete') ) @@ -123,7 +126,7 @@ class ContactAssignmentTable(NetBoxTable): model = ContactAssignment fields = ( 'pk', 'content_type', 'object', 'contact', 'role', 'priority', 'contact_title', 'contact_phone', - 'contact_email', 'contact_address', 'contact_link', 'contact_description', 'actions' + 'contact_email', 'contact_address', 'contact_link', 'contact_description', 'tags', 'actions' ) default_columns = ( 'pk', 'content_type', 'object', 'contact', 'role', 'priority', 'contact_email', 'contact_phone'