1from django.core.exceptions import ValidationError 2from django.db import models 3from django.urls import reverse 4from mptt.models import MPTTModel, TreeForeignKey 5 6from extras.utils import extras_features 7from netbox.models import NestedGroupModel, PrimaryModel 8from utilities.querysets import RestrictedQuerySet 9 10 11__all__ = ( 12 'Tenant', 13 'TenantGroup', 14) 15 16 17@extras_features('custom_fields', 'custom_links', 'export_templates', 'webhooks') 18class TenantGroup(NestedGroupModel): 19 """ 20 An arbitrary collection of Tenants. 21 """ 22 name = models.CharField( 23 max_length=100, 24 unique=True 25 ) 26 slug = models.SlugField( 27 max_length=100, 28 unique=True 29 ) 30 parent = TreeForeignKey( 31 to='self', 32 on_delete=models.CASCADE, 33 related_name='children', 34 blank=True, 35 null=True, 36 db_index=True 37 ) 38 description = models.CharField( 39 max_length=200, 40 blank=True 41 ) 42 43 class Meta: 44 ordering = ['name'] 45 46 def get_absolute_url(self): 47 return reverse('tenancy:tenantgroup', args=[self.pk]) 48 49 50@extras_features('custom_fields', 'custom_links', 'export_templates', 'tags', 'webhooks') 51class Tenant(PrimaryModel): 52 """ 53 A Tenant represents an organization served by the NetBox owner. This is typically a customer or an internal 54 department. 55 """ 56 name = models.CharField( 57 max_length=100, 58 unique=True 59 ) 60 slug = models.SlugField( 61 max_length=100, 62 unique=True 63 ) 64 group = models.ForeignKey( 65 to='tenancy.TenantGroup', 66 on_delete=models.SET_NULL, 67 related_name='tenants', 68 blank=True, 69 null=True 70 ) 71 description = models.CharField( 72 max_length=200, 73 blank=True 74 ) 75 comments = models.TextField( 76 blank=True 77 ) 78 79 objects = RestrictedQuerySet.as_manager() 80 81 clone_fields = [ 82 'group', 'description', 83 ] 84 85 class Meta: 86 ordering = ['name'] 87 88 def __str__(self): 89 return self.name 90 91 def get_absolute_url(self): 92 return reverse('tenancy:tenant', args=[self.pk]) 93