contacts.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. from django.contrib.contenttypes.fields import GenericForeignKey
  2. from django.contrib.contenttypes.models import ContentType
  3. from django.db import models
  4. from django.urls import reverse
  5. from netbox.models import ChangeLoggedModel, NestedGroupModel, OrganizationalModel, PrimaryModel
  6. from tenancy.choices import *
  7. __all__ = (
  8. 'ContactAssignment',
  9. 'Contact',
  10. 'ContactGroup',
  11. 'ContactRole',
  12. )
  13. class ContactGroup(NestedGroupModel):
  14. """
  15. An arbitrary collection of Contacts.
  16. """
  17. class Meta:
  18. ordering = ['name']
  19. constraints = (
  20. models.UniqueConstraint(
  21. fields=('parent', 'name'),
  22. name='%(app_label)s_%(class)s_unique_parent_name'
  23. ),
  24. )
  25. def get_absolute_url(self):
  26. return reverse('tenancy:contactgroup', args=[self.pk])
  27. class ContactRole(OrganizationalModel):
  28. """
  29. Functional role for a Contact assigned to an object.
  30. """
  31. def get_absolute_url(self):
  32. return reverse('tenancy:contactrole', args=[self.pk])
  33. class Contact(PrimaryModel):
  34. """
  35. Contact information for a particular object(s) in NetBox.
  36. """
  37. group = models.ForeignKey(
  38. to='tenancy.ContactGroup',
  39. on_delete=models.SET_NULL,
  40. related_name='contacts',
  41. blank=True,
  42. null=True
  43. )
  44. name = models.CharField(
  45. max_length=100
  46. )
  47. title = models.CharField(
  48. max_length=100,
  49. blank=True
  50. )
  51. phone = models.CharField(
  52. max_length=50,
  53. blank=True
  54. )
  55. email = models.EmailField(
  56. blank=True
  57. )
  58. address = models.CharField(
  59. max_length=200,
  60. blank=True
  61. )
  62. link = models.URLField(
  63. blank=True
  64. )
  65. clone_fields = (
  66. 'group', 'name', 'title', 'phone', 'email', 'address', 'link',
  67. )
  68. class Meta:
  69. ordering = ['name']
  70. constraints = (
  71. models.UniqueConstraint(
  72. fields=('group', 'name'),
  73. name='%(app_label)s_%(class)s_unique_group_name'
  74. ),
  75. )
  76. def __str__(self):
  77. return self.name
  78. def get_absolute_url(self):
  79. return reverse('tenancy:contact', args=[self.pk])
  80. class ContactAssignment(ChangeLoggedModel):
  81. content_type = models.ForeignKey(
  82. to=ContentType,
  83. on_delete=models.CASCADE
  84. )
  85. object_id = models.PositiveBigIntegerField()
  86. object = GenericForeignKey(
  87. ct_field='content_type',
  88. fk_field='object_id'
  89. )
  90. contact = models.ForeignKey(
  91. to='tenancy.Contact',
  92. on_delete=models.PROTECT,
  93. related_name='assignments'
  94. )
  95. role = models.ForeignKey(
  96. to='tenancy.ContactRole',
  97. on_delete=models.PROTECT,
  98. related_name='assignments'
  99. )
  100. priority = models.CharField(
  101. max_length=50,
  102. choices=ContactPriorityChoices,
  103. blank=True
  104. )
  105. clone_fields = ('content_type', 'object_id', 'role', 'priority')
  106. class Meta:
  107. ordering = ('priority', 'contact')
  108. constraints = (
  109. models.UniqueConstraint(
  110. fields=('content_type', 'object_id', 'contact', 'role'),
  111. name='%(app_label)s_%(class)s_unique_object_contact_role'
  112. ),
  113. )
  114. def __str__(self):
  115. if self.priority:
  116. return f"{self.contact} ({self.get_priority_display()}) -> {self.object}"
  117. return str(f"{self.contact} -> {self.object}")
  118. def get_absolute_url(self):
  119. return reverse('tenancy:contact', args=[self.contact.pk])
  120. def to_objectchange(self, action):
  121. objectchange = super().to_objectchange(action)
  122. objectchange.related_object = self.object
  123. return objectchange