models.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. from django.db import models
  2. from django.urls import reverse
  3. from mptt.models import MPTTModel, TreeForeignKey
  4. from taggit.managers import TaggableManager
  5. from extras.models import ChangeLoggedModel, CustomFieldModel, ObjectChange, TaggedItem
  6. from extras.utils import extras_features
  7. from utilities.mptt import TreeManager
  8. from utilities.querysets import RestrictedQuerySet
  9. from utilities.utils import serialize_object
  10. __all__ = (
  11. 'Tenant',
  12. 'TenantGroup',
  13. )
  14. class TenantGroup(MPTTModel, ChangeLoggedModel):
  15. """
  16. An arbitrary collection of Tenants.
  17. """
  18. name = models.CharField(
  19. max_length=100,
  20. unique=True
  21. )
  22. slug = models.SlugField(
  23. max_length=100,
  24. unique=True
  25. )
  26. parent = TreeForeignKey(
  27. to='self',
  28. on_delete=models.CASCADE,
  29. related_name='children',
  30. blank=True,
  31. null=True,
  32. db_index=True
  33. )
  34. description = models.CharField(
  35. max_length=200,
  36. blank=True
  37. )
  38. objects = TreeManager()
  39. csv_headers = ['name', 'slug', 'parent', 'description']
  40. class Meta:
  41. ordering = ['name']
  42. class MPTTMeta:
  43. order_insertion_by = ['name']
  44. def __str__(self):
  45. return self.name
  46. def get_absolute_url(self):
  47. return "{}?group={}".format(reverse('tenancy:tenant_list'), self.slug)
  48. def to_csv(self):
  49. return (
  50. self.name,
  51. self.slug,
  52. self.parent.name if self.parent else '',
  53. self.description,
  54. )
  55. def to_objectchange(self, action):
  56. # Remove MPTT-internal fields
  57. return ObjectChange(
  58. changed_object=self,
  59. object_repr=str(self),
  60. action=action,
  61. object_data=serialize_object(self, exclude=['level', 'lft', 'rght', 'tree_id'])
  62. )
  63. @extras_features('custom_fields', 'custom_links', 'export_templates', 'webhooks')
  64. class Tenant(ChangeLoggedModel, CustomFieldModel):
  65. """
  66. A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal
  67. department.
  68. """
  69. name = models.CharField(
  70. max_length=100,
  71. unique=True
  72. )
  73. slug = models.SlugField(
  74. max_length=100,
  75. unique=True
  76. )
  77. group = models.ForeignKey(
  78. to='tenancy.TenantGroup',
  79. on_delete=models.SET_NULL,
  80. related_name='tenants',
  81. blank=True,
  82. null=True
  83. )
  84. description = models.CharField(
  85. max_length=200,
  86. blank=True
  87. )
  88. comments = models.TextField(
  89. blank=True
  90. )
  91. tags = TaggableManager(through=TaggedItem)
  92. objects = RestrictedQuerySet.as_manager()
  93. csv_headers = ['name', 'slug', 'group', 'description', 'comments']
  94. clone_fields = [
  95. 'group', 'description',
  96. ]
  97. class Meta:
  98. ordering = ['group', 'name']
  99. def __str__(self):
  100. return self.name
  101. def get_absolute_url(self):
  102. return reverse('tenancy:tenant', args=[self.slug])
  103. def to_csv(self):
  104. return (
  105. self.name,
  106. self.slug,
  107. self.group.name if self.group else None,
  108. self.description,
  109. self.comments,
  110. )