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:
5
docs/core-functionality/contacts.md
Normal file
5
docs/core-functionality/contacts.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Contacts
|
||||
|
||||
{!models/tenancy/contact.md!}
|
||||
{!models/tenancy/contactgroup.md!}
|
||||
{!models/tenancy/contactrole.md!}
|
31
docs/models/tenancy/contact.md
Normal file
31
docs/models/tenancy/contact.md
Normal 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
|
3
docs/models/tenancy/contactgroup.md
Normal file
3
docs/models/tenancy/contactgroup.md
Normal 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.
|
3
docs/models/tenancy/contactrole.md
Normal file
3
docs/models/tenancy/contactrole.md
Normal 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.
|
@ -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'
|
||||
|
@ -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',
|
||||
]
|
||||
|
@ -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']
|
||||
|
@ -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']
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user