浏览代码

Add contact/role assignment tables

jeremystretch 4 年之前
父节点
当前提交
faf1e6a43d
共有 4 个文件被更改,包括 56 次插入7 次删除
  1. 13 0
      netbox/templates/tenancy/contact.html
  2. 6 0
      netbox/templates/tenancy/contactrole.html
  3. 18 5
      netbox/tenancy/tables.py
  4. 19 2
      netbox/tenancy/views.py

+ 13 - 0
netbox/templates/tenancy/contact.html

@@ -46,6 +46,12 @@
               <td>Address</td>
               <td>{{ object.address|linebreaksbr|placeholder }}</td>
             </tr>
+            <tr>
+              <th scope="row">Assignments</th>
+              <td>
+                <a href="{% url 'tenancy:contact_list' %}?contact_id={{ object.pk }}">{{ assignment_count }}</a>
+              </td>
+            </tr>
           </table>
         </div>
       </div>
@@ -60,6 +66,13 @@
   </div>
   <div class="row">
     <div class="col col-md-12">
+      <div class="card">
+        <h5 class="card-header">Assignments</h5>
+        <div class="card-body">
+          {% include 'inc/table.html' with table=contacts_table %}
+        </div>
+      </div>
+      {% include 'inc/paginator.html' with paginator=contacts_table.paginator page=contacts_table.page %}
       {% plugin_full_width_page object %}
     </div>
   </div>

+ 6 - 0
netbox/templates/tenancy/contactrole.html

@@ -21,6 +21,12 @@
               <th scope="row">Description</th>
               <td>{{ object.description|placeholder }}</td>
             </tr>
+            <tr>
+              <th scope="row">Assignments</th>
+              <td>
+                <a href="{% url 'tenancy:contact_list' %}?role={{ object.slug }}">{{ assignment_count }}</a>
+              </td>
+            </tr>
           </table>
         </div>
       </div>

+ 18 - 5
netbox/tenancy/tables.py

@@ -1,7 +1,7 @@
 import django_tables2 as tables
 
 from utilities.tables import (
-    BaseTable, ButtonsColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn,
+    BaseTable, ButtonsColumn, ContentTypeColumn, LinkedCountColumn, MarkdownColumn, MPTTColumn, TagColumn, ToggleColumn,
 )
 from .models import *
 
@@ -126,23 +126,36 @@ class ContactTable(BaseTable):
         linkify=True
     )
     comments = MarkdownColumn()
+    assignment_count = tables.Column(
+        verbose_name='Assignments'
+    )
     tags = TagColumn(
         url_name='tenancy:tenant_list'
     )
 
     class Meta(BaseTable.Meta):
         model = Contact
-        fields = ('pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'tags')
-        default_columns = ('pk', 'name', 'group', 'title', 'phone', 'email')
+        fields = ('pk', 'name', 'group', 'title', 'phone', 'email', 'address', 'comments', 'assignment_count', 'tags')
+        default_columns = ('pk', 'name', 'group', 'assignment_count', 'title', 'phone', 'email')
 
 
 class ContactAssignmentTable(BaseTable):
     pk = ToggleColumn()
+    content_type = ContentTypeColumn(
+        verbose_name='Object Type'
+    )
+    object = tables.Column(
+        linkify=True,
+        orderable=False
+    )
     contact = tables.Column(
         linkify=True
     )
+    role = tables.Column(
+        linkify=True
+    )
 
     class Meta(BaseTable.Meta):
         model = ContactAssignment
-        fields = ('pk', 'contact', 'role', 'priority')
-        default_columns = ('pk', 'contact', 'role', 'priority')
+        fields = ('pk', 'content_type', 'object', 'contact', 'role', 'priority')
+        default_columns = ('pk', 'object', 'contact', 'role', 'priority')

+ 19 - 2
netbox/tenancy/views.py

@@ -7,6 +7,7 @@ from dcim.models import Site, Rack, Device, RackReservation
 from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
 from netbox.views import generic
 from utilities.tables import paginate_table
+from utilities.utils import count_related
 from virtualization.models import VirtualMachine, Cluster
 from . import filtersets, forms, tables
 from .models import *
@@ -236,11 +237,12 @@ class ContactRoleView(generic.ObjectView):
             role=instance
         )
         contacts_table = tables.ContactAssignmentTable(contact_assignments)
+        contacts_table.columns.hide('role')
         paginate_table(contacts_table, request)
 
         return {
             'contacts_table': contacts_table,
-            'contact_count': ContactAssignment.objects.filter(role=instance).count(),
+            'assignment_count': ContactAssignment.objects.filter(role=instance).count(),
         }
 
 
@@ -276,7 +278,9 @@ class ContactRoleBulkDeleteView(generic.BulkDeleteView):
 #
 
 class ContactListView(generic.ObjectListView):
-    queryset = Contact.objects.all()
+    queryset = Contact.objects.annotate(
+        assignment_count=count_related(ContactAssignment, 'contact')
+    )
     filterset = filtersets.ContactFilterSet
     filterset_form = forms.ContactFilterForm
     table = tables.ContactTable
@@ -285,6 +289,19 @@ class ContactListView(generic.ObjectListView):
 class ContactView(generic.ObjectView):
     queryset = Contact.objects.all()
 
+    def get_extra_context(self, request, instance):
+        contact_assignments = ContactAssignment.objects.restrict(request.user, 'view').filter(
+            contact=instance
+        )
+        contacts_table = tables.ContactAssignmentTable(contact_assignments)
+        contacts_table.columns.hide('contact')
+        paginate_table(contacts_table, request)
+
+        return {
+            'contacts_table': contacts_table,
+            'assignment_count': ContactAssignment.objects.filter(contact=instance).count(),
+        }
+
 
 class ContactEditView(generic.ObjectEditView):
     queryset = Contact.objects.all()