Skip to content

Commit 864db46

Browse files
Fixes: #18305 make contacts mixin available for plugins (#19029)
1 parent 1508e3a commit 864db46

File tree

9 files changed

+38
-131
lines changed

9 files changed

+38
-131
lines changed

docs/plugins/development/models.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ For more information about database migrations, see the [Django documentation](h
117117

118118
::: netbox.models.features.CloningMixin
119119

120+
::: netbox.models.features.ContactsMixin
121+
120122
::: netbox.models.features.CustomLinksMixin
121123

122124
::: netbox.models.features.CustomFieldsMixin

netbox/circuits/views.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from dcim.views import PathTraceView
77
from netbox.views import generic
8-
from tenancy.views import ObjectContactsView
98
from utilities.forms import ConfirmationForm
109
from utilities.query import count_related
1110
from utilities.views import GetRelatedModelsMixin, register_model_view
@@ -74,11 +73,6 @@ class ProviderBulkDeleteView(generic.BulkDeleteView):
7473
table = tables.ProviderTable
7574

7675

77-
@register_model_view(Provider, 'contacts')
78-
class ProviderContactsView(ObjectContactsView):
79-
queryset = Provider.objects.all()
80-
81-
8276
#
8377
# ProviderAccounts
8478
#
@@ -141,11 +135,6 @@ class ProviderAccountBulkDeleteView(generic.BulkDeleteView):
141135
table = tables.ProviderAccountTable
142136

143137

144-
@register_model_view(ProviderAccount, 'contacts')
145-
class ProviderAccountContactsView(ObjectContactsView):
146-
queryset = ProviderAccount.objects.all()
147-
148-
149138
#
150139
# Provider networks
151140
#
@@ -413,11 +402,6 @@ def post(self, request, pk):
413402
})
414403

415404

416-
@register_model_view(Circuit, 'contacts')
417-
class CircuitContactsView(ObjectContactsView):
418-
queryset = Circuit.objects.all()
419-
420-
421405
#
422406
# Circuit terminations
423407
#

netbox/dcim/views.py

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
2020
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
2121
from netbox.views import generic
22-
from tenancy.views import ObjectContactsView
2322
from utilities.forms import ConfirmationForm
2423
from utilities.paginator import EnhancedPaginator, get_paginate_count
2524
from utilities.permissions import get_permission_for_model
@@ -304,11 +303,6 @@ class RegionBulkDeleteView(generic.BulkDeleteView):
304303
table = tables.RegionTable
305304

306305

307-
@register_model_view(Region, 'contacts')
308-
class RegionContactsView(ObjectContactsView):
309-
queryset = Region.objects.all()
310-
311-
312306
#
313307
# Site groups
314308
#
@@ -412,11 +406,6 @@ class SiteGroupBulkDeleteView(generic.BulkDeleteView):
412406
table = tables.SiteGroupTable
413407

414408

415-
@register_model_view(SiteGroup, 'contacts')
416-
class SiteGroupContactsView(ObjectContactsView):
417-
queryset = SiteGroup.objects.all()
418-
419-
420409
#
421410
# Sites
422411
#
@@ -494,11 +483,6 @@ class SiteBulkDeleteView(generic.BulkDeleteView):
494483
table = tables.SiteTable
495484

496485

497-
@register_model_view(Site, 'contacts')
498-
class SiteContactsView(ObjectContactsView):
499-
queryset = Site.objects.all()
500-
501-
502486
#
503487
# Locations
504488
#
@@ -596,11 +580,6 @@ class LocationBulkDeleteView(generic.BulkDeleteView):
596580
table = tables.LocationTable
597581

598582

599-
@register_model_view(Location, 'contacts')
600-
class LocationContactsView(ObjectContactsView):
601-
queryset = Location.objects.all()
602-
603-
604583
#
605584
# Rack roles
606585
#
@@ -887,11 +866,6 @@ class RackBulkDeleteView(generic.BulkDeleteView):
887866
table = tables.RackTable
888867

889868

890-
@register_model_view(Rack, 'contacts')
891-
class RackContactsView(ObjectContactsView):
892-
queryset = Rack.objects.all()
893-
894-
895869
#
896870
# Rack reservations
897871
#
@@ -1029,11 +1003,6 @@ class ManufacturerBulkDeleteView(generic.BulkDeleteView):
10291003
table = tables.ManufacturerTable
10301004

10311005

1032-
@register_model_view(Manufacturer, 'contacts')
1033-
class ManufacturerContactsView(ObjectContactsView):
1034-
queryset = Manufacturer.objects.all()
1035-
1036-
10371006
#
10381007
# Device types
10391008
#
@@ -2360,11 +2329,6 @@ class DeviceBulkRenameView(generic.BulkRenameView):
23602329
table = tables.DeviceTable
23612330

23622331

2363-
@register_model_view(Device, 'contacts')
2364-
class DeviceContactsView(ObjectContactsView):
2365-
queryset = Device.objects.all()
2366-
2367-
23682332
#
23692333
# Modules
23702334
#
@@ -3924,11 +3888,6 @@ class PowerPanelBulkDeleteView(generic.BulkDeleteView):
39243888
table = tables.PowerPanelTable
39253889

39263890

3927-
@register_model_view(PowerPanel, 'contacts')
3928-
class PowerPanelContactsView(ObjectContactsView):
3929-
queryset = PowerPanel.objects.all()
3930-
3931-
39323891
#
39333892
# Power feeds
39343893
#

netbox/ipam/views.py

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from dcim.models import Interface, Site
1212
from ipam.tables import VLANTranslationRuleTable
1313
from netbox.views import generic
14-
from tenancy.views import ObjectContactsView
1514
from utilities.query import count_related
1615
from utilities.tables import get_table_ordering
1716
from utilities.views import GetRelatedModelsMixin, ViewTab, register_model_view
@@ -434,11 +433,6 @@ class AggregateBulkDeleteView(generic.BulkDeleteView):
434433
table = tables.AggregateTable
435434

436435

437-
@register_model_view(Aggregate, 'contacts')
438-
class AggregateContactsView(ObjectContactsView):
439-
queryset = Aggregate.objects.all()
440-
441-
442436
#
443437
# Prefix/VLAN roles
444438
#
@@ -684,11 +678,6 @@ class PrefixBulkDeleteView(generic.BulkDeleteView):
684678
table = tables.PrefixTable
685679

686680

687-
@register_model_view(Prefix, 'contacts')
688-
class PrefixContactsView(ObjectContactsView):
689-
queryset = Prefix.objects.all()
690-
691-
692681
#
693682
# IP Ranges
694683
#
@@ -778,11 +767,6 @@ class IPRangeBulkDeleteView(generic.BulkDeleteView):
778767
table = tables.IPRangeTable
779768

780769

781-
@register_model_view(IPRange, 'contacts')
782-
class IPRangeContactsView(ObjectContactsView):
783-
queryset = IPRange.objects.all()
784-
785-
786770
#
787771
# IP addresses
788772
#
@@ -964,11 +948,6 @@ def get_children(self, request, parent):
964948
return parent.get_related_ips().restrict(request.user, 'view')
965949

966950

967-
@register_model_view(IPAddress, 'contacts')
968-
class IPAddressContactsView(ObjectContactsView):
969-
queryset = IPAddress.objects.all()
970-
971-
972951
#
973952
# VLAN groups
974953
#
@@ -1476,8 +1455,3 @@ class ServiceBulkDeleteView(generic.BulkDeleteView):
14761455
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
14771456
filterset = filtersets.ServiceFilterSet
14781457
table = tables.ServiceTable
1479-
1480-
1481-
@register_model_view(Service, 'contacts')
1482-
class ServiceContactsView(ObjectContactsView):
1483-
queryset = Service.objects.all()

netbox/netbox/models/features.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ class Meta:
353353

354354
class ContactsMixin(models.Model):
355355
"""
356-
Enables the assignments of Contacts (via ContactAssignment).
356+
Enables the assignment of Contacts to a model (via ContactAssignment).
357357
"""
358358
contacts = GenericRelation(
359359
to='tenancy.ContactAssignment',
@@ -368,7 +368,8 @@ def get_contacts(self, inherited=True):
368368
"""
369369
Return a `QuerySet` matching all contacts assigned to this object.
370370
371-
:param inherited: If `True`, inherited contacts from parent objects are included.
371+
Args:
372+
inherited: If `True`, inherited contacts from parent objects are included.
372373
"""
373374
from tenancy.models import ContactAssignment
374375
from . import NestedGroupModel
@@ -659,6 +660,10 @@ def register_models(*models):
659660
)
660661

661662
# Register applicable feature views for the model
663+
if issubclass(model, ContactsMixin):
664+
register_model_view(model, 'contacts', kwargs={'model': model})(
665+
'netbox.views.generic.ObjectContactsView'
666+
)
662667
if issubclass(model, JournalingMixin):
663668
register_model_view(model, 'journal', kwargs={'model': model})(
664669
'netbox.views.generic.ObjectJournalView'

netbox/netbox/views/generic/feature_views.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,19 @@
1212
from extras.forms import JournalEntryForm
1313
from extras.models import JournalEntry
1414
from extras.tables import JournalEntryTable
15+
from tenancy.models import ContactAssignment
16+
from tenancy.tables import ContactAssignmentTable
17+
from tenancy.filtersets import ContactAssignmentFilterSet
18+
from tenancy.forms import ContactAssignmentFilterForm
1519
from utilities.permissions import get_permission_for_model
1620
from utilities.views import ConditionalLoginRequiredMixin, GetReturnURLMixin, ViewTab
1721
from .base import BaseMultiObjectView
22+
from .object_views import ObjectChildrenView
1823

1924
__all__ = (
2025
'BulkSyncDataView',
2126
'ObjectChangeLogView',
27+
'ObjectContactsView',
2228
'ObjectJobsView',
2329
'ObjectJournalView',
2430
'ObjectSyncDataView',
@@ -244,3 +250,25 @@ def post(self, request):
244250
))
245251

246252
return redirect(self.get_return_url(request))
253+
254+
255+
class ObjectContactsView(ObjectChildrenView):
256+
child_model = ContactAssignment
257+
table = ContactAssignmentTable
258+
filterset = ContactAssignmentFilterSet
259+
filterset_form = ContactAssignmentFilterForm
260+
template_name = 'tenancy/object_contacts.html'
261+
tab = ViewTab(
262+
label=_('Contacts'),
263+
badge=lambda obj: obj.get_contacts().count(),
264+
permission='tenancy.view_contactassignment',
265+
weight=5000
266+
)
267+
268+
def dispatch(self, request, *args, **kwargs):
269+
model = kwargs.pop('model')
270+
self.queryset = model.objects.all()
271+
return super().dispatch(request, *args, **kwargs)
272+
273+
def get_children(self, request, parent):
274+
return parent.get_contacts().restrict(request.user, 'view').order_by('priority', 'contact', 'role')

netbox/tenancy/views.py

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
from django.contrib.contenttypes.models import ContentType
22
from django.shortcuts import get_object_or_404
3-
from django.utils.translation import gettext_lazy as _
43

54
from netbox.views import generic
65
from utilities.query import count_related
7-
from utilities.views import GetRelatedModelsMixin, ViewTab, register_model_view
6+
from utilities.views import GetRelatedModelsMixin, register_model_view
87
from . import filtersets, forms, tables
98
from .models import *
109

1110

12-
class ObjectContactsView(generic.ObjectChildrenView):
13-
child_model = ContactAssignment
14-
table = tables.ContactAssignmentTable
15-
filterset = filtersets.ContactAssignmentFilterSet
16-
filterset_form = forms.ContactAssignmentFilterForm
17-
template_name = 'tenancy/object_contacts.html'
18-
tab = ViewTab(
19-
label=_('Contacts'),
20-
badge=lambda obj: obj.get_contacts().count(),
21-
permission='tenancy.view_contactassignment',
22-
weight=5000
23-
)
24-
25-
def get_children(self, request, parent):
26-
return parent.get_contacts().restrict(request.user, 'view').order_by('priority', 'contact', 'role')
27-
28-
2911
#
3012
# Tenant groups
3113
#
@@ -156,11 +138,6 @@ class TenantBulkDeleteView(generic.BulkDeleteView):
156138
table = tables.TenantTable
157139

158140

159-
@register_model_view(Tenant, 'contacts')
160-
class TenantContactsView(ObjectContactsView):
161-
queryset = Tenant.objects.all()
162-
163-
164141
#
165142
# Contact groups
166143
#

netbox/virtualization/views.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from ipam.tables import InterfaceVLANTable, VLANTranslationRuleTable
1717
from netbox.constants import DEFAULT_ACTION_PERMISSIONS
1818
from netbox.views import generic
19-
from tenancy.views import ObjectContactsView
2019
from utilities.query import count_related
2120
from utilities.query_functions import CollateAsChar
2221
from utilities.views import GetRelatedModelsMixin, ViewTab, register_model_view
@@ -148,11 +147,6 @@ class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
148147
table = tables.ClusterGroupTable
149148

150149

151-
@register_model_view(ClusterGroup, 'contacts')
152-
class ClusterGroupContactsView(ObjectContactsView):
153-
queryset = ClusterGroup.objects.all()
154-
155-
156150
#
157151
# Clusters
158152
#
@@ -344,11 +338,6 @@ def post(self, request, pk):
344338
})
345339

346340

347-
@register_model_view(Cluster, 'contacts')
348-
class ClusterContactsView(ObjectContactsView):
349-
queryset = Cluster.objects.all()
350-
351-
352341
#
353342
# Virtual machines
354343
#
@@ -509,11 +498,6 @@ class VirtualMachineBulkDeleteView(generic.BulkDeleteView):
509498
table = tables.VirtualMachineTable
510499

511500

512-
@register_model_view(VirtualMachine, 'contacts')
513-
class VirtualMachineContactsView(ObjectContactsView):
514-
queryset = VirtualMachine.objects.all()
515-
516-
517501
#
518502
# VM interfaces
519503
#

0 commit comments

Comments
 (0)