Browse Source

Closes #412: Tenant group assignment is no longer mandatory

Jeremy Stretch 8 years ago
parent
commit
bc9158a74f

+ 14 - 1
docs/data-model/tenancy.md

@@ -4,6 +4,19 @@ NetBox supports the concept of individual tenants within its parent organization
 
 A tenant represents a discrete organization. Certain resources within NetBox can be assigned to a tenant. This makes it very convenient to track which resources are assigned to which customers, for instance.
 
+The following objects can be assigned to tenants:
+
+* Sites
+* Racks
+* Devices
+* VRFs
+* Prefixes
+* IP addresses
+* VLANs
+* Circuits
+
+If a prefix or IP address is not assigned to a tenant, it will appear to inherit the tenant to which its parent VRF is assigned, if any.
+
 ### Tenant Groups
 
-Tenants are grouped by type. For instance, you might create one group called "Customers" and one called "Acquisitions."
+Tenants can be grouped by type. For instance, you might create one group called "Customers" and one called "Acquisitions." The assignment of tenants to groups is optional.

+ 14 - 2
netbox/tenancy/forms.py

@@ -8,6 +8,18 @@ from utilities.forms import (
 from .models import Tenant, TenantGroup
 
 
+def bulkedit_tenantgroup_choices():
+    """
+    Include an option to remove the currently assigned TenantGroup from a Tenant.
+    """
+    choices = [
+        (None, '---------'),
+        (0, 'None'),
+    ]
+    choices += [(g.pk, g.name) for g in TenantGroup.objects.all()]
+    return choices
+
+
 def bulkedit_tenant_choices():
     """
     Include an option to remove the currently assigned Tenant from an object.
@@ -46,7 +58,7 @@ class TenantForm(forms.ModelForm, BootstrapMixin):
 
 
 class TenantFromCSVForm(forms.ModelForm):
-    group = forms.ModelChoiceField(TenantGroup.objects.all(), to_field_name='name',
+    group = forms.ModelChoiceField(TenantGroup.objects.all(), required=False, to_field_name='name',
                                    error_messages={'invalid_choice': 'Group not found.'})
 
     class Meta:
@@ -60,7 +72,7 @@ class TenantImportForm(BulkImportForm, BootstrapMixin):
 
 class TenantBulkEditForm(forms.Form, BootstrapMixin):
     pk = forms.ModelMultipleChoiceField(queryset=Tenant.objects.all(), widget=forms.MultipleHiddenInput)
-    group = forms.ModelChoiceField(queryset=TenantGroup.objects.all(), required=False)
+    group = forms.TypedChoiceField(choices=bulkedit_tenantgroup_choices, coerce=int, required=False, label='Group')
 
 
 def tenant_group_choices():

+ 21 - 0
netbox/tenancy/migrations/0002_tenant_group_optional.py

@@ -0,0 +1,21 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.8 on 2016-08-02 19:54
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('tenancy', '0001_initial'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='tenant',
+            name='group',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='tenants', to='tenancy.TenantGroup'),
+        ),
+    ]

+ 1 - 1
netbox/tenancy/models.py

@@ -28,7 +28,7 @@ class Tenant(CreatedUpdatedModel):
     """
     name = models.CharField(max_length=30, unique=True)
     slug = models.SlugField(unique=True)
-    group = models.ForeignKey('TenantGroup', related_name='tenants', on_delete=models.PROTECT)
+    group = models.ForeignKey('TenantGroup', related_name='tenants', blank=True, null=True, on_delete=models.SET_NULL)
     description = models.CharField(max_length=100, blank=True, help_text="Long-form name (optional)")
     comments = models.TextField(blank=True)
 

+ 4 - 3
netbox/tenancy/views.py

@@ -99,9 +99,10 @@ class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
     def update_objects(self, pk_list, form):
 
         fields_to_update = {}
-        for field in ['group']:
-            if form.cleaned_data[field]:
-                fields_to_update[field] = form.cleaned_data[field]
+        if form.cleaned_data['group'] == 0:
+            fields_to_update['group'] = None
+        elif form.cleaned_data['group']:
+            fields_to_update['group'] = form.cleaned_data['group']
 
         return self.cls.objects.filter(pk__in=pk_list).update(**fields_to_update)