1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Cleanup and documentation for #1344

This commit is contained in:
jeremystretch
2021-10-18 16:20:31 -04:00
parent f485a47b48
commit 487d67768b
10 changed files with 79 additions and 8 deletions

View File

@ -0,0 +1,5 @@
# Contacts
{!models/tenancy/contact.md!}
{!models/tenancy/contactgroup.md!}
{!models/tenancy/contactrole.md!}

View File

@ -0,0 +1,31 @@
# Contacts
A contact represent an individual or group that has been associated with an object in NetBox for administrative reasons. For example, you might assign one or more operational contacts to each site. Contacts can be arranged within nested contact groups.
Each contact must include a name, which is unique to its parent group (if any). The following optional descriptors are also available:
* Title
* Phone
* Email
* Address
## Contact Assignment
Each contact can be assigned to one or more objects, allowing for the efficient reuse of contact information. When assigning a contact to an object, the user may optionally specify a role and/or priority (primary, secondary, tertiary, or inactive) to better convey the nature of the contact's relationship to the assigned object.
The following models support the assignment of contacts:
* circuits.Circuit
* circuits.Provider
* dcim.Device
* dcim.Location
* dcim.Manufacturer
* dcim.PowerPanel
* dcim.Rack
* dcim.Region
* dcim.Site
* dcim.SiteGroup
* tenancy.Tenant
* virtualization.Cluster
* virtualization.ClusterGroup
* virtualization.VirtualMachine

View File

@ -0,0 +1,3 @@
# Contact Groups
Contacts can be organized into arbitrary groups. These groups can be recursively nested for convenience. Each contact within a group must have a unique name, but other attributes can be repeated.

View File

@ -0,0 +1,3 @@
# Contact Roles
Contacts can be organized by functional roles, which are fully customizable by the user. For example, you might create roles for administrative, operational, or emergency contacts.

View File

@ -62,6 +62,7 @@ nav:
- Circuits: 'core-functionality/circuits.md'
- Power Tracking: 'core-functionality/power.md'
- Tenancy: 'core-functionality/tenancy.md'
- Contacts: 'core-functionality/contacts.md'
- Customization:
- Custom Fields: 'customization/custom-fields.md'
- Custom Validation: 'customization/custom-validation.md'

View File

@ -1,8 +1,9 @@
from django.contrib.auth.models import ContentType
from rest_framework import serializers
from netbox.api import ContentTypeField
from netbox.api import ChoiceField, ContentTypeField
from netbox.api.serializers import NestedGroupModelSerializer, OrganizationalModelSerializer, PrimaryModelSerializer
from tenancy.choices import ContactPriorityChoices
from tenancy.models import *
from .nested_serializers import *
@ -93,9 +94,11 @@ class ContactAssignmentSerializer(PrimaryModelSerializer):
)
contact = NestedContactSerializer()
role = NestedContactRoleSerializer(required=False, allow_null=True)
priority = ChoiceField(choices=ContactPriorityChoices, required=False)
class Meta:
model = ContactAssignment
fields = [
'id', 'url', 'display', 'content_type', 'object_id', 'contact', 'role', 'created', 'last_updated',
'id', 'url', 'display', 'content_type', 'object_id', 'contact', 'role', 'priority', 'created',
'last_updated',
]

View File

@ -2,8 +2,8 @@ import django_filters
from django.db.models import Q
from extras.filters import TagFilter
from netbox.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from utilities.filters import TreeNodeMultipleChoiceFilter
from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter
from .models import *
@ -168,7 +168,8 @@ class ContactFilterSet(PrimaryModelFilterSet):
)
class ContactAssignmentFilterSet(OrganizationalModelFilterSet):
class ContactAssignmentFilterSet(ChangeLoggedModelFilterSet):
content_type = ContentTypeFilter()
contact_id = django_filters.ModelMultipleChoiceFilter(
queryset=Contact.objects.all(),
label='Contact (ID)',
@ -186,4 +187,4 @@ class ContactAssignmentFilterSet(OrganizationalModelFilterSet):
class Meta:
model = ContactAssignment
fields = ['id', 'priority']
fields = ['id', 'content_type_id', 'priority']

View File

@ -96,6 +96,21 @@ class ContactBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldModelBul
queryset=ContactGroup.objects.all(),
required=False
)
title = forms.CharField(
max_length=100,
required=False
)
phone = forms.CharField(
max_length=50,
required=False
)
email = forms.EmailField(
required=False
)
address = forms.CharField(
max_length=200,
required=False
)
class Meta:
nullable_fields = ['group', 'title', 'phone', 'email', 'address', 'comments']

View File

@ -109,10 +109,16 @@ class ContactForm(BootstrapMixin, CustomFieldModelForm):
class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
group = DynamicModelChoiceField(
queryset=ContactGroup.objects.all(),
required=False
required=False,
initial_params={
'contacts': '$contact'
}
)
contact = DynamicModelChoiceField(
queryset=Contact.objects.all()
queryset=Contact.objects.all(),
query_params={
'group_id': '$group'
}
)
role = DynamicModelChoiceField(
queryset=ContactRole.objects.all()

View File

@ -259,3 +259,6 @@ class ContactAssignment(ChangeLoggedModel):
class Meta:
ordering = ('priority', 'contact')
def __str__(self):
return f"{self.contact} ({self.get_priority_display()})" if self.priority else self.name