mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-23 04:22:01 -06:00
Adds contact tabs (#12460)
* adds contact tabs #11599 * fixed lint issues * changes as per review * changes as per review * replaces generic object template with base template
This commit is contained in:
parent
e71a98499f
commit
4eb5e90ccc
@ -1,10 +1,10 @@
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db import transaction
|
from django.db import transaction
|
||||||
from django.db.models import Q
|
|
||||||
from django.shortcuts import get_object_or_404, redirect, render
|
from django.shortcuts import get_object_or_404, redirect, render
|
||||||
|
|
||||||
from dcim.views import PathTraceView
|
from dcim.views import PathTraceView
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
|
from tenancy.views import ObjectContactsView
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import register_model_view
|
from utilities.views import register_model_view
|
||||||
@ -73,6 +73,11 @@ class ProviderBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.ProviderTable
|
table = tables.ProviderTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Provider, 'contacts')
|
||||||
|
class ProviderContactsView(ObjectContactsView):
|
||||||
|
queryset = Provider.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# ProviderAccounts
|
# ProviderAccounts
|
||||||
#
|
#
|
||||||
@ -134,6 +139,11 @@ class ProviderAccountBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.ProviderAccountTable
|
table = tables.ProviderAccountTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(ProviderAccount, 'contacts')
|
||||||
|
class ProviderAccountContactsView(ObjectContactsView):
|
||||||
|
queryset = ProviderAccount.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Provider networks
|
# Provider networks
|
||||||
#
|
#
|
||||||
@ -389,6 +399,11 @@ class CircuitSwapTerminations(generic.ObjectEditView):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Circuit, 'contacts')
|
||||||
|
class CircuitContactsView(ObjectContactsView):
|
||||||
|
queryset = Circuit.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Circuit terminations
|
# Circuit terminations
|
||||||
#
|
#
|
||||||
|
@ -20,6 +20,7 @@ from extras.views import ObjectConfigContextView
|
|||||||
from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup
|
from ipam.models import ASN, IPAddress, Prefix, VLAN, VLANGroup
|
||||||
from ipam.tables import InterfaceVLANTable
|
from ipam.tables import InterfaceVLANTable
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
|
from tenancy.views import ObjectContactsView
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
@ -267,6 +268,11 @@ class RegionBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.RegionTable
|
table = tables.RegionTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Region, 'contacts')
|
||||||
|
class RegionContactsView(ObjectContactsView):
|
||||||
|
queryset = Region.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Site groups
|
# Site groups
|
||||||
#
|
#
|
||||||
@ -342,6 +348,11 @@ class SiteGroupBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.SiteGroupTable
|
table = tables.SiteGroupTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(SiteGroup, 'contacts')
|
||||||
|
class SiteGroupContactsView(ObjectContactsView):
|
||||||
|
queryset = SiteGroup.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Sites
|
# Sites
|
||||||
#
|
#
|
||||||
@ -435,6 +446,11 @@ class SiteBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.SiteTable
|
table = tables.SiteTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Site, 'contacts')
|
||||||
|
class SiteContactsView(ObjectContactsView):
|
||||||
|
queryset = Site.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Locations
|
# Locations
|
||||||
#
|
#
|
||||||
@ -523,6 +539,11 @@ class LocationBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.LocationTable
|
table = tables.LocationTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Location, 'contacts')
|
||||||
|
class LocationContactsView(ObjectContactsView):
|
||||||
|
queryset = Location.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Rack roles
|
# Rack roles
|
||||||
#
|
#
|
||||||
@ -740,6 +761,11 @@ class RackBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.RackTable
|
table = tables.RackTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Rack, 'contacts')
|
||||||
|
class RackContactsView(ObjectContactsView):
|
||||||
|
queryset = Rack.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Rack reservations
|
# Rack reservations
|
||||||
#
|
#
|
||||||
@ -874,6 +900,11 @@ class ManufacturerBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.ManufacturerTable
|
table = tables.ManufacturerTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Manufacturer, 'contacts')
|
||||||
|
class ManufacturerContactsView(ObjectContactsView):
|
||||||
|
queryset = Manufacturer.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Device types
|
# Device types
|
||||||
#
|
#
|
||||||
@ -2088,6 +2119,11 @@ class DeviceBulkRenameView(generic.BulkRenameView):
|
|||||||
table = tables.DeviceTable
|
table = tables.DeviceTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Device, 'contacts')
|
||||||
|
class DeviceContactsView(ObjectContactsView):
|
||||||
|
queryset = Device.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Modules
|
# Modules
|
||||||
#
|
#
|
||||||
@ -3469,6 +3505,11 @@ class PowerPanelBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.PowerPanelTable
|
table = tables.PowerPanelTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(PowerPanel, 'contacts')
|
||||||
|
class PowerPanelContactsView(ObjectContactsView):
|
||||||
|
queryset = PowerPanel.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Power feeds
|
# Power feeds
|
||||||
#
|
#
|
||||||
|
@ -9,6 +9,7 @@ from circuits.models import Provider
|
|||||||
from dcim.filtersets import InterfaceFilterSet
|
from dcim.filtersets import InterfaceFilterSet
|
||||||
from dcim.models import Interface, Site
|
from dcim.models import Interface, Site
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
|
from tenancy.views import ObjectContactsView
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import ViewTab, register_model_view
|
from utilities.views import ViewTab, register_model_view
|
||||||
from virtualization.filtersets import VMInterfaceFilterSet
|
from virtualization.filtersets import VMInterfaceFilterSet
|
||||||
@ -1300,6 +1301,11 @@ class L2VPNBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.L2VPNTable
|
table = tables.L2VPNTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(L2VPN, 'contacts')
|
||||||
|
class L2VPNContactsView(ObjectContactsView):
|
||||||
|
queryset = L2VPN.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# L2VPN terminations
|
# L2VPN terminations
|
||||||
#
|
#
|
||||||
|
@ -70,7 +70,6 @@
|
|||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_a side='A' %}
|
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_a side='A' %}
|
||||||
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_z side='Z' %}
|
{% include 'circuits/inc/circuit_termination.html' with termination=object.termination_z side='Z' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/comments.html' %}
|
{% include 'inc/panels/comments.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-12">
|
<div class="col col-md-12">
|
||||||
|
@ -298,7 +298,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">Dimensions</h5>
|
<h5 class="card-header">Dimensions</h5>
|
||||||
|
@ -65,7 +65,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% include 'dcim/inc/nonracked_devices.html' %}
|
{% include 'dcim/inc/nonracked_devices.html' %}
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
|
@ -51,7 +51,6 @@
|
|||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,7 +40,6 @@
|
|||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% include 'inc/panels/image_attachments.html' %}
|
{% include 'inc/panels/image_attachments.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -191,7 +191,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'dcim/inc/nonracked_devices.html' %}
|
{% include 'dcim/inc/nonracked_devices.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -131,7 +131,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' with filter_name='site_id' %}
|
{% include 'inc/panels/related_objects.html' with filter_name='site_id' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<h5 class="card-header">Locations</h5>
|
<h5 class="card-header">Locations</h5>
|
||||||
<div class='card-body'>
|
<div class='card-body'>
|
||||||
|
@ -42,7 +42,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'inc/panels/tags.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
|
@ -1,63 +0,0 @@
|
|||||||
{% load helpers %}
|
|
||||||
|
|
||||||
<div class="card">
|
|
||||||
<h5 class="card-header">Contacts</h5>
|
|
||||||
<div class="card-body">
|
|
||||||
{% with contacts=object.contacts.all %}
|
|
||||||
{% if contacts.exists %}
|
|
||||||
<table class="table table-hover">
|
|
||||||
<tr>
|
|
||||||
<th>Name</th>
|
|
||||||
<th>Role</th>
|
|
||||||
<th>Priority</th>
|
|
||||||
<th>Phone</th>
|
|
||||||
<th>Email</th>
|
|
||||||
<th></th>
|
|
||||||
</tr>
|
|
||||||
{% for contact in contacts %}
|
|
||||||
<tr>
|
|
||||||
<td>{{ contact.contact|linkify }}</td>
|
|
||||||
<td>{{ contact.role|placeholder }}</td>
|
|
||||||
<td>{{ contact.get_priority_display|placeholder }}</td>
|
|
||||||
<td>
|
|
||||||
{% if contact.contact.phone %}
|
|
||||||
<a href="tel:{{ contact.contact.phone }}">{{ contact.contact.phone }}</a>
|
|
||||||
{% else %}
|
|
||||||
{{ ''|placeholder }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% if contact.contact.email %}
|
|
||||||
<a href="mailto:{{ contact.contact.email }}">{{ contact.contact.email }}</a>
|
|
||||||
{% else %}
|
|
||||||
{{ ''|placeholder }}
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
<td class="text-end noprint">
|
|
||||||
{% if perms.tenancy.change_contactassignment %}
|
|
||||||
<a href="{% url 'tenancy:contactassignment_edit' pk=contact.pk %}?return_url={{ object.get_absolute_url }}" class="btn btn-warning btn-sm lh-1" title="Edit">
|
|
||||||
<i class="mdi mdi-pencil" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
{% if perms.tenancy.delete_contactassignment %}
|
|
||||||
<a href="{% url 'tenancy:contactassignment_delete' pk=contact.pk %}?return_url={{ object.get_absolute_url }}" class="btn btn-danger btn-sm lh-1" title="Delete">
|
|
||||||
<i class="mdi mdi-trash-can-outline" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% endfor %}
|
|
||||||
</table>
|
|
||||||
{% else %}
|
|
||||||
<div class="text-muted">None</div>
|
|
||||||
{% endif %}
|
|
||||||
{% endwith %}
|
|
||||||
</div>
|
|
||||||
{% if perms.tenancy.add_contactassignment %}
|
|
||||||
<div class="card-footer text-end noprint">
|
|
||||||
<a href="{% url 'tenancy:contactassignment_add' %}?content_type={{ object|content_type_id }}&object_id={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm">
|
|
||||||
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add a contact
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
|
@ -37,7 +37,6 @@
|
|||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/comments.html' %}
|
{% include 'inc/panels/comments.html' %}
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
|
27
netbox/templates/tenancy/object_contacts.html
Normal file
27
netbox/templates/tenancy/object_contacts.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{% extends base_template %}
|
||||||
|
{% load helpers %}
|
||||||
|
|
||||||
|
{% block extra_controls %}
|
||||||
|
{% if perms.tenancy.add_contactassignment %}
|
||||||
|
<a href="{% url 'tenancy:contactassignment_add' %}?content_type={{ object|content_type_id }}&object_id={{ object.pk }}&return_url={{ object.get_absolute_url }}" class="btn btn-primary btn-sm">
|
||||||
|
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Add a contact
|
||||||
|
</a>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% include 'inc/table_controls_htmx.html' with table_modal="ContactTable_config" %}
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body" id="object_list">
|
||||||
|
{% include 'htmx/table.html' %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock content %}
|
||||||
|
|
||||||
|
{% block modals %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% table_config_form table %}
|
||||||
|
{% endblock modals %}
|
@ -30,7 +30,6 @@
|
|||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'inc/panels/tags.html' %}
|
||||||
{% include 'inc/panels/comments.html' %}
|
{% include 'inc/panels/comments.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_left_page object %}
|
{% plugin_left_page object %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col col-md-5">
|
<div class="col col-md-5">
|
||||||
|
@ -84,7 +84,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/tags.html' %}
|
{% include 'inc/panels/tags.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
<div class="col col-md-6">
|
<div class="col col-md-6">
|
||||||
{% include 'inc/panels/related_objects.html' %}
|
{% include 'inc/panels/related_objects.html' %}
|
||||||
{% include 'inc/panels/custom_fields.html' %}
|
{% include 'inc/panels/custom_fields.html' %}
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -158,7 +158,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% include 'inc/panels/contacts.html' %}
|
|
||||||
{% plugin_right_page object %}
|
{% plugin_right_page object %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,17 +7,40 @@ from dcim.models import Cable, Device, Location, Rack, RackReservation, Site, Vi
|
|||||||
from ipam.models import Aggregate, ASN, IPAddress, IPRange, L2VPN, Prefix, VLAN, VRF
|
from ipam.models import Aggregate, ASN, IPAddress, IPRange, L2VPN, Prefix, VLAN, VRF
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import register_model_view
|
from utilities.views import register_model_view, ViewTab
|
||||||
from virtualization.models import VirtualMachine, Cluster
|
from virtualization.models import VirtualMachine, Cluster
|
||||||
from wireless.models import WirelessLAN, WirelessLink
|
from wireless.models import WirelessLAN, WirelessLink
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
from .models import *
|
from .models import *
|
||||||
|
|
||||||
|
|
||||||
|
class ObjectContactsView(generic.ObjectChildrenView):
|
||||||
|
child_model = Contact
|
||||||
|
table = tables.ContactTable
|
||||||
|
filterset = filtersets.ContactFilterSet
|
||||||
|
template_name = 'tenancy/object_contacts.html'
|
||||||
|
tab = ViewTab(
|
||||||
|
label=_('Contacts'),
|
||||||
|
badge=lambda obj: obj.contacts.count(),
|
||||||
|
permission='tenancy.view_contact',
|
||||||
|
weight=5000
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_children(self, request, parent):
|
||||||
|
return Contact.objects.annotate(
|
||||||
|
assignment_count=count_related(ContactAssignment, 'contact')
|
||||||
|
).restrict(request.user, 'view').filter(assignments__object_id=parent.pk)
|
||||||
|
|
||||||
|
def get_extra_context(self, request, instance):
|
||||||
|
return {
|
||||||
|
'base_template': f'{instance._meta.app_label}/{instance._meta.model_name}.html',
|
||||||
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
# Tenant groups
|
# Tenant groups
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class TenantGroupListView(generic.ObjectListView):
|
class TenantGroupListView(generic.ObjectListView):
|
||||||
queryset = TenantGroup.objects.add_related_count(
|
queryset = TenantGroup.objects.add_related_count(
|
||||||
TenantGroup.objects.all(),
|
TenantGroup.objects.all(),
|
||||||
@ -165,6 +188,11 @@ class TenantBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.TenantTable
|
table = tables.TenantTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Tenant, 'contacts')
|
||||||
|
class TenantContactsView(ObjectContactsView):
|
||||||
|
queryset = Tenant.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Contact groups
|
# Contact groups
|
||||||
#
|
#
|
||||||
@ -342,11 +370,11 @@ class ContactBulkDeleteView(generic.BulkDeleteView):
|
|||||||
filterset = filtersets.ContactFilterSet
|
filterset = filtersets.ContactFilterSet
|
||||||
table = tables.ContactTable
|
table = tables.ContactTable
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Contact assignments
|
# Contact assignments
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class ContactAssignmentListView(generic.ObjectListView):
|
class ContactAssignmentListView(generic.ObjectListView):
|
||||||
queryset = ContactAssignment.objects.all()
|
queryset = ContactAssignment.objects.all()
|
||||||
filterset = filtersets.ContactAssignmentFilterSet
|
filterset = filtersets.ContactAssignmentFilterSet
|
||||||
|
@ -9,9 +9,10 @@ from dcim.filtersets import DeviceFilterSet
|
|||||||
from dcim.models import Device
|
from dcim.models import Device
|
||||||
from dcim.tables import DeviceTable
|
from dcim.tables import DeviceTable
|
||||||
from extras.views import ObjectConfigContextView
|
from extras.views import ObjectConfigContextView
|
||||||
from ipam.models import IPAddress, Service
|
from ipam.models import IPAddress
|
||||||
from ipam.tables import InterfaceVLANTable
|
from ipam.tables import InterfaceVLANTable
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
|
from tenancy.views import ObjectContactsView
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import ViewTab, register_model_view
|
from utilities.views import ViewTab, register_model_view
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
@ -140,6 +141,11 @@ class ClusterGroupBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.ClusterGroupTable
|
table = tables.ClusterGroupTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(ClusterGroup, 'contacts')
|
||||||
|
class ClusterGroupContactsView(ObjectContactsView):
|
||||||
|
queryset = ClusterGroup.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Clusters
|
# Clusters
|
||||||
#
|
#
|
||||||
@ -312,6 +318,11 @@ class ClusterRemoveDevicesView(generic.ObjectEditView):
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(Cluster, 'contacts')
|
||||||
|
class ClusterContactsView(ObjectContactsView):
|
||||||
|
queryset = Cluster.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Virtual machines
|
# Virtual machines
|
||||||
#
|
#
|
||||||
@ -390,6 +401,11 @@ class VirtualMachineBulkDeleteView(generic.BulkDeleteView):
|
|||||||
table = tables.VirtualMachineTable
|
table = tables.VirtualMachineTable
|
||||||
|
|
||||||
|
|
||||||
|
@register_model_view(VirtualMachine, 'contacts')
|
||||||
|
class VirtualMachineContactsView(ObjectContactsView):
|
||||||
|
queryset = VirtualMachine.objects.all()
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# VM interfaces
|
# VM interfaces
|
||||||
#
|
#
|
||||||
|
Loading…
Reference in New Issue
Block a user