Просмотр исходного кода

Merge pull request #4178 from netbox-community/4081-drop-ip-family

Closes #4081: Drop the family column from IP objects
Jeremy Stretch 6 лет назад
Родитель
Сommit
f6cbce65fa

+ 1 - 0
docs/release-notes/version-2.7.md

@@ -9,6 +9,7 @@
 
 
 * [#2519](https://github.com/netbox-community/netbox/issues/2519) - Avoid race condition when provisioning "next available" IPs/prefixes via the API
 * [#2519](https://github.com/netbox-community/netbox/issues/2519) - Avoid race condition when provisioning "next available" IPs/prefixes via the API
 * [#4168](https://github.com/netbox-community/netbox/issues/4168) - Role is not required when creating a virtual machine
 * [#4168](https://github.com/netbox-community/netbox/issues/4168) - Role is not required when creating a virtual machine
+* [#4175](https://github.com/netbox-community/netbox/issues/4175) - Fix potential exception when bulk editing objects from a filtered list
 
 
 ---
 ---
 
 

+ 2 - 2
netbox/dcim/forms.py

@@ -1857,14 +1857,14 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
 
 
                 # Collect interface IPs
                 # Collect interface IPs
                 interface_ips = IPAddress.objects.prefetch_related('interface').filter(
                 interface_ips = IPAddress.objects.prefetch_related('interface').filter(
-                    family=family, interface_id__in=interface_ids
+                    address__family=family, interface_id__in=interface_ids
                 )
                 )
                 if interface_ips:
                 if interface_ips:
                     ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips]
                     ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips]
                     ip_choices.append(('Interface IPs', ip_list))
                     ip_choices.append(('Interface IPs', ip_list))
                 # Collect NAT IPs
                 # Collect NAT IPs
                 nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
                 nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
-                    family=family, nat_inside__interface__in=interface_ids
+                    address__family=family, nat_inside__interface__in=interface_ids
                 )
                 )
                 if nat_ips:
                 if nat_ips:
                     ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.nat_inside.address)) for ip in nat_ips]
                     ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.nat_inside.address)) for ip in nat_ips]

+ 2 - 2
netbox/dcim/tests/test_filters.py

@@ -1144,8 +1144,8 @@ class DeviceTestCase(TestCase):
 
 
         # Assign primary IPs for filtering
         # Assign primary IPs for filtering
         ipaddresses = (
         ipaddresses = (
-            IPAddress(family=4, address='192.0.2.1/24', interface=interfaces[0]),
-            IPAddress(family=4, address='192.0.2.2/24', interface=interfaces[1]),
+            IPAddress(address='192.0.2.1/24', interface=interfaces[0]),
+            IPAddress(address='192.0.2.2/24', interface=interfaces[1]),
         )
         )
         IPAddress.objects.bulk_create(ipaddresses)
         IPAddress.objects.bulk_create(ipaddresses)
         Device.objects.filter(pk=devices[0].pk).update(primary_ip4=ipaddresses[0])
         Device.objects.filter(pk=devices[0].pk).update(primary_ip4=ipaddresses[0])

+ 2 - 0
netbox/ipam/fields.py

@@ -63,6 +63,7 @@ IPNetworkField.register_lookup(lookups.NetContained)
 IPNetworkField.register_lookup(lookups.NetContainedOrEqual)
 IPNetworkField.register_lookup(lookups.NetContainedOrEqual)
 IPNetworkField.register_lookup(lookups.NetContains)
 IPNetworkField.register_lookup(lookups.NetContains)
 IPNetworkField.register_lookup(lookups.NetContainsOrEquals)
 IPNetworkField.register_lookup(lookups.NetContainsOrEquals)
+IPNetworkField.register_lookup(lookups.NetFamily)
 IPNetworkField.register_lookup(lookups.NetMaskLength)
 IPNetworkField.register_lookup(lookups.NetMaskLength)
 
 
 
 
@@ -90,4 +91,5 @@ IPAddressField.register_lookup(lookups.NetContainsOrEquals)
 IPAddressField.register_lookup(lookups.NetHost)
 IPAddressField.register_lookup(lookups.NetHost)
 IPAddressField.register_lookup(lookups.NetIn)
 IPAddressField.register_lookup(lookups.NetIn)
 IPAddressField.register_lookup(lookups.NetHostContained)
 IPAddressField.register_lookup(lookups.NetHostContained)
+IPAddressField.register_lookup(lookups.NetFamily)
 IPAddressField.register_lookup(lookups.NetMaskLength)
 IPAddressField.register_lookup(lookups.NetMaskLength)

+ 15 - 3
netbox/ipam/filters.py

@@ -73,6 +73,10 @@ class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
         method='search',
         method='search',
         label='Search',
         label='Search',
     )
     )
+    family = django_filters.NumberFilter(
+        field_name='prefix',
+        lookup_expr='family'
+    )
     prefix = django_filters.CharFilter(
     prefix = django_filters.CharFilter(
         method='filter_prefix',
         method='filter_prefix',
         label='Prefix',
         label='Prefix',
@@ -91,7 +95,7 @@ class AggregateFilterSet(CustomFieldFilterSet, CreatedUpdatedFilterSet):
 
 
     class Meta:
     class Meta:
         model = Aggregate
         model = Aggregate
-        fields = ['family', 'date_added']
+        fields = ('date_added',)
 
 
     def search(self, queryset, name, value):
     def search(self, queryset, name, value):
         if not value.strip():
         if not value.strip():
@@ -134,6 +138,10 @@ class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt
         method='search',
         method='search',
         label='Search',
         label='Search',
     )
     )
+    family = django_filters.NumberFilter(
+        field_name='prefix',
+        lookup_expr='family'
+    )
     prefix = django_filters.CharFilter(
     prefix = django_filters.CharFilter(
         method='filter_prefix',
         method='filter_prefix',
         label='Prefix',
         label='Prefix',
@@ -211,7 +219,7 @@ class PrefixFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt
 
 
     class Meta:
     class Meta:
         model = Prefix
         model = Prefix
-        fields = ['family', 'is_pool']
+        fields = ('is_pool',)
 
 
     def search(self, queryset, name, value):
     def search(self, queryset, name, value):
         if not value.strip():
         if not value.strip():
@@ -282,6 +290,10 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF
         method='search',
         method='search',
         label='Search',
         label='Search',
     )
     )
+    family = django_filters.NumberFilter(
+        field_name='address',
+        lookup_expr='family'
+    )
     parent = django_filters.CharFilter(
     parent = django_filters.CharFilter(
         method='search_by_parent',
         method='search_by_parent',
         label='Parent prefix',
         label='Parent prefix',
@@ -350,7 +362,7 @@ class IPAddressFilterSet(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedF
 
 
     class Meta:
     class Meta:
         model = IPAddress
         model = IPAddress
-        fields = ['family', 'dns_name']
+        fields = ('dns_name',)
 
 
     def search(self, queryset, name, value):
     def search(self, queryset, name, value):
         if not value.strip():
         if not value.strip():

+ 9 - 0
netbox/ipam/lookups.py

@@ -154,6 +154,15 @@ class NetHostContained(Lookup):
         return 'CAST(HOST(%s) AS INET) << %s' % (lhs, rhs), params
         return 'CAST(HOST(%s) AS INET) << %s' % (lhs, rhs), params
 
 
 
 
+class NetFamily(Transform):
+    lookup_name = 'family'
+    function = 'FAMILY'
+
+    @property
+    def output_field(self):
+        return IntegerField()
+
+
 class NetMaskLength(Transform):
 class NetMaskLength(Transform):
     lookup_name = 'net_mask_length'
     lookup_name = 'net_mask_length'
     function = 'MASKLEN'
     function = 'MASKLEN'

+ 1 - 1
netbox/ipam/managers.py

@@ -13,4 +13,4 @@ class IPAddressManager(models.Manager):
         IP address as a /32 or /128.
         IP address as a /32 or /128.
         """
         """
         qs = super().get_queryset()
         qs = super().get_queryset()
-        return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('family', 'host')
+        return qs.annotate(host=RawSQL('INET(HOST(ipam_ipaddress.address))', [])).order_by('host')

+ 38 - 0
netbox/ipam/migrations/0035_drop_ip_family.py

@@ -0,0 +1,38 @@
+# Generated by Django 2.2.9 on 2020-02-14 19:36
+
+from django.db import migrations
+import django.db.models.expressions
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('ipam', '0034_fix_ipaddress_status_dhcp'),
+    ]
+
+    operations = [
+        migrations.AlterModelOptions(
+            name='aggregate',
+            options={'ordering': ('prefix', 'pk')},
+        ),
+        migrations.AlterModelOptions(
+            name='ipaddress',
+            options={'ordering': ('address', 'pk'), 'verbose_name': 'IP address', 'verbose_name_plural': 'IP addresses'},
+        ),
+        migrations.AlterModelOptions(
+            name='prefix',
+            options={'ordering': (django.db.models.expressions.OrderBy(django.db.models.expressions.F('vrf'), nulls_first=True), 'prefix', 'pk'), 'verbose_name_plural': 'prefixes'},
+        ),
+        migrations.RemoveField(
+            model_name='aggregate',
+            name='family',
+        ),
+        migrations.RemoveField(
+            model_name='ipaddress',
+            name='family',
+        ),
+        migrations.RemoveField(
+            model_name='prefix',
+            name='family',
+        ),
+    ]

+ 26 - 32
netbox/ipam/models.py

@@ -150,9 +150,6 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
     An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize
     An aggregate exists at the root level of the IP address space hierarchy in NetBox. Aggregates are used to organize
     the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
     the hierarchy and track the overall utilization of available address space. Each Aggregate is assigned to a RIR.
     """
     """
-    family = models.PositiveSmallIntegerField(
-        choices=IPAddressFamilyChoices
-    )
     prefix = IPNetworkField()
     prefix = IPNetworkField()
     rir = models.ForeignKey(
     rir = models.ForeignKey(
         to='ipam.RIR',
         to='ipam.RIR',
@@ -182,7 +179,7 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
     ]
     ]
 
 
     class Meta:
     class Meta:
-        ordering = ('family', 'prefix', 'pk')  # (family, prefix) may be non-unique
+        ordering = ('prefix', 'pk')  # prefix may be non-unique
 
 
     def __str__(self):
     def __str__(self):
         return str(self.prefix)
         return str(self.prefix)
@@ -225,12 +222,6 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
                     )
                     )
                 })
                 })
 
 
-    def save(self, *args, **kwargs):
-        if self.prefix:
-            # Infer address family from IPNetwork object
-            self.family = self.prefix.version
-        super().save(*args, **kwargs)
-
     def to_csv(self):
     def to_csv(self):
         return (
         return (
             self.prefix,
             self.prefix,
@@ -239,6 +230,12 @@ class Aggregate(ChangeLoggedModel, CustomFieldModel):
             self.description,
             self.description,
         )
         )
 
 
+    @property
+    def family(self):
+        if self.prefix:
+            return self.prefix.version
+        return None
+
     def get_utilization(self):
     def get_utilization(self):
         """
         """
         Determine the prefix utilization of the aggregate and return it as a percentage.
         Determine the prefix utilization of the aggregate and return it as a percentage.
@@ -291,10 +288,6 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
     VRFs. A Prefix must be assigned a status and may optionally be assigned a used-define Role. A Prefix can also be
     VRFs. A Prefix must be assigned a status and may optionally be assigned a used-define Role. A Prefix can also be
     assigned to a VLAN where appropriate.
     assigned to a VLAN where appropriate.
     """
     """
-    family = models.PositiveSmallIntegerField(
-        choices=IPAddressFamilyChoices,
-        editable=False
-    )
     prefix = IPNetworkField(
     prefix = IPNetworkField(
         help_text='IPv4 or IPv6 network with mask'
         help_text='IPv4 or IPv6 network with mask'
     )
     )
@@ -376,7 +369,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
     }
     }
 
 
     class Meta:
     class Meta:
-        ordering = (F('vrf').asc(nulls_first=True), 'family', 'prefix', 'pk')  # (vrf, family, prefix) may be non-unique
+        ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk')  # (vrf, prefix) may be non-unique
         verbose_name_plural = 'prefixes'
         verbose_name_plural = 'prefixes'
 
 
     def __str__(self):
     def __str__(self):
@@ -423,9 +416,6 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
             # Clear host bits from prefix
             # Clear host bits from prefix
             self.prefix = self.prefix.cidr
             self.prefix = self.prefix.cidr
 
 
-            # Record address family
-            self.family = self.prefix.version
-
         super().save(*args, **kwargs)
         super().save(*args, **kwargs)
 
 
     def to_csv(self):
     def to_csv(self):
@@ -442,6 +432,12 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
             self.description,
             self.description,
         )
         )
 
 
+    @property
+    def family(self):
+        if self.prefix:
+            return self.prefix.version
+        return None
+
     def _set_prefix_length(self, value):
     def _set_prefix_length(self, value):
         """
         """
         Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
         Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
@@ -501,9 +497,9 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
 
 
         # All IP addresses within a point-to-point prefix (IPv4 /31 or IPv6 /127) are considered usable
         # All IP addresses within a point-to-point prefix (IPv4 /31 or IPv6 /127) are considered usable
         if (
         if (
-            self.family == 4 and self.prefix.prefixlen == 31  # RFC 3021
+            self.prefix.version == 4 and self.prefix.prefixlen == 31  # RFC 3021
         ) or (
         ) or (
-            self.family == 6 and self.prefix.prefixlen == 127  # RFC 6164
+            self.prefix.version == 6 and self.prefix.prefixlen == 127  # RFC 6164
         ):
         ):
             return available_ips
             return available_ips
 
 
@@ -546,7 +542,7 @@ class Prefix(ChangeLoggedModel, CustomFieldModel):
             # Compile an IPSet to avoid counting duplicate IPs
             # Compile an IPSet to avoid counting duplicate IPs
             child_count = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]).size
             child_count = netaddr.IPSet([ip.address.ip for ip in self.get_child_ips()]).size
             prefix_size = self.prefix.size
             prefix_size = self.prefix.size
-            if self.family == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
+            if self.prefix.version == 4 and self.prefix.prefixlen < 31 and not self.is_pool:
                 prefix_size -= 2
                 prefix_size -= 2
             return int(float(child_count) / prefix_size * 100)
             return int(float(child_count) / prefix_size * 100)
 
 
@@ -562,10 +558,6 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
     for example, when mapping public addresses to private addresses. When an Interface has been assigned an IPAddress
     for example, when mapping public addresses to private addresses. When an Interface has been assigned an IPAddress
     which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
     which has a NAT outside IP, that Interface's Device can use either the inside or outside IP as its primary IP.
     """
     """
-    family = models.PositiveSmallIntegerField(
-        choices=IPAddressFamilyChoices,
-        editable=False
-    )
     address = IPAddressField(
     address = IPAddressField(
         help_text='IPv4 or IPv6 address (with mask)'
         help_text='IPv4 or IPv6 address (with mask)'
     )
     )
@@ -659,7 +651,7 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
     }
     }
 
 
     class Meta:
     class Meta:
-        ordering = ('family', 'address', 'pk')  # (family, address) may be non-unique
+        ordering = ('address', 'pk')  # address may be non-unique
         verbose_name = 'IP address'
         verbose_name = 'IP address'
         verbose_name_plural = 'IP addresses'
         verbose_name_plural = 'IP addresses'
 
 
@@ -727,10 +719,6 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
 
 
     def save(self, *args, **kwargs):
     def save(self, *args, **kwargs):
 
 
-        # Record address family
-        if isinstance(self.address, netaddr.IPNetwork):
-            self.family = self.address.version
-
         # Force dns_name to lowercase
         # Force dns_name to lowercase
         self.dns_name = self.dns_name.lower()
         self.dns_name = self.dns_name.lower()
 
 
@@ -754,9 +742,9 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
     def to_csv(self):
     def to_csv(self):
 
 
         # Determine if this IP is primary for a Device
         # Determine if this IP is primary for a Device
-        if self.family == 4 and getattr(self, 'primary_ip4_for', False):
+        if self.address.version == 4 and getattr(self, 'primary_ip4_for', False):
             is_primary = True
             is_primary = True
-        elif self.family == 6 and getattr(self, 'primary_ip6_for', False):
+        elif self.address.version == 6 and getattr(self, 'primary_ip6_for', False):
             is_primary = True
             is_primary = True
         else:
         else:
             is_primary = False
             is_primary = False
@@ -775,6 +763,12 @@ class IPAddress(ChangeLoggedModel, CustomFieldModel):
             self.description,
             self.description,
         )
         )
 
 
+    @property
+    def family(self):
+        if self.address:
+            return self.address.version
+        return None
+
     def _set_mask_length(self, value):
     def _set_mask_length(self, value):
         """
         """
         Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,
         Expose the IPNetwork object's prefixlen attribute on the parent model so that it can be manipulated directly,

+ 26 - 26
netbox/ipam/tests/test_filters.py

@@ -96,12 +96,12 @@ class AggregateTestCase(TestCase):
         RIR.objects.bulk_create(rirs)
         RIR.objects.bulk_create(rirs)
 
 
         aggregates = (
         aggregates = (
-            Aggregate(family=4, prefix='10.1.0.0/16', rir=rirs[0], date_added='2020-01-01'),
-            Aggregate(family=4, prefix='10.2.0.0/16', rir=rirs[0], date_added='2020-01-02'),
-            Aggregate(family=4, prefix='10.3.0.0/16', rir=rirs[1], date_added='2020-01-03'),
-            Aggregate(family=6, prefix='2001:db8:1::/48', rir=rirs[1], date_added='2020-01-04'),
-            Aggregate(family=6, prefix='2001:db8:2::/48', rir=rirs[2], date_added='2020-01-05'),
-            Aggregate(family=6, prefix='2001:db8:3::/48', rir=rirs[2], date_added='2020-01-06'),
+            Aggregate(prefix='10.1.0.0/16', rir=rirs[0], date_added='2020-01-01'),
+            Aggregate(prefix='10.2.0.0/16', rir=rirs[0], date_added='2020-01-02'),
+            Aggregate(prefix='10.3.0.0/16', rir=rirs[1], date_added='2020-01-03'),
+            Aggregate(prefix='2001:db8:1::/48', rir=rirs[1], date_added='2020-01-04'),
+            Aggregate(prefix='2001:db8:2::/48', rir=rirs[2], date_added='2020-01-05'),
+            Aggregate(prefix='2001:db8:3::/48', rir=rirs[2], date_added='2020-01-06'),
         )
         )
         Aggregate.objects.bulk_create(aggregates)
         Aggregate.objects.bulk_create(aggregates)
 
 
@@ -199,16 +199,16 @@ class PrefixTestCase(TestCase):
         Role.objects.bulk_create(roles)
         Role.objects.bulk_create(roles)
 
 
         prefixes = (
         prefixes = (
-            Prefix(family=4, prefix='10.0.0.0/24', site=None, vrf=None, vlan=None, role=None, is_pool=True),
-            Prefix(family=4, prefix='10.0.1.0/24', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]),
-            Prefix(family=4, prefix='10.0.2.0/24', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED),
-            Prefix(family=4, prefix='10.0.3.0/24', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED),
-            Prefix(family=6, prefix='2001:db8::/64', site=None, vrf=None, vlan=None, role=None, is_pool=True),
-            Prefix(family=6, prefix='2001:db8:0:1::/64', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]),
-            Prefix(family=6, prefix='2001:db8:0:2::/64', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED),
-            Prefix(family=6, prefix='2001:db8:0:3::/64', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED),
-            Prefix(family=4, prefix='10.0.0.0/16'),
-            Prefix(family=6, prefix='2001:db8::/32'),
+            Prefix(prefix='10.0.0.0/24', site=None, vrf=None, vlan=None, role=None, is_pool=True),
+            Prefix(prefix='10.0.1.0/24', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]),
+            Prefix(prefix='10.0.2.0/24', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED),
+            Prefix(prefix='10.0.3.0/24', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED),
+            Prefix(prefix='2001:db8::/64', site=None, vrf=None, vlan=None, role=None, is_pool=True),
+            Prefix(prefix='2001:db8:0:1::/64', site=sites[0], vrf=vrfs[0], vlan=vlans[0], role=roles[0]),
+            Prefix(prefix='2001:db8:0:2::/64', site=sites[1], vrf=vrfs[1], vlan=vlans[1], role=roles[1], status=PrefixStatusChoices.STATUS_DEPRECATED),
+            Prefix(prefix='2001:db8:0:3::/64', site=sites[2], vrf=vrfs[2], vlan=vlans[2], role=roles[2], status=PrefixStatusChoices.STATUS_RESERVED),
+            Prefix(prefix='10.0.0.0/16'),
+            Prefix(prefix='2001:db8::/32'),
         )
         )
         Prefix.objects.bulk_create(prefixes)
         Prefix.objects.bulk_create(prefixes)
 
 
@@ -333,16 +333,16 @@ class IPAddressTestCase(TestCase):
         Interface.objects.bulk_create(interfaces)
         Interface.objects.bulk_create(interfaces)
 
 
         ipaddresses = (
         ipaddresses = (
-            IPAddress(family=4, address='10.0.0.1/24', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'),
-            IPAddress(family=4, address='10.0.0.2/24', vrf=vrfs[0], interface=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'),
-            IPAddress(family=4, address='10.0.0.3/24', vrf=vrfs[1], interface=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'),
-            IPAddress(family=4, address='10.0.0.4/24', vrf=vrfs[2], interface=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'),
-            IPAddress(family=4, address='10.0.0.1/25', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE),
-            IPAddress(family=6, address='2001:db8::1/64', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'),
-            IPAddress(family=6, address='2001:db8::2/64', vrf=vrfs[0], interface=interfaces[3], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'),
-            IPAddress(family=6, address='2001:db8::3/64', vrf=vrfs[1], interface=interfaces[4], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'),
-            IPAddress(family=6, address='2001:db8::4/64', vrf=vrfs[2], interface=interfaces[5], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'),
-            IPAddress(family=6, address='2001:db8::1/65', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE),
+            IPAddress(address='10.0.0.1/24', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'),
+            IPAddress(address='10.0.0.2/24', vrf=vrfs[0], interface=interfaces[0], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'),
+            IPAddress(address='10.0.0.3/24', vrf=vrfs[1], interface=interfaces[1], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'),
+            IPAddress(address='10.0.0.4/24', vrf=vrfs[2], interface=interfaces[2], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'),
+            IPAddress(address='10.0.0.1/25', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE),
+            IPAddress(address='2001:db8::1/64', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-a'),
+            IPAddress(address='2001:db8::2/64', vrf=vrfs[0], interface=interfaces[3], status=IPAddressStatusChoices.STATUS_ACTIVE, dns_name='ipaddress-b'),
+            IPAddress(address='2001:db8::3/64', vrf=vrfs[1], interface=interfaces[4], status=IPAddressStatusChoices.STATUS_RESERVED, role=IPAddressRoleChoices.ROLE_VIP, dns_name='ipaddress-c'),
+            IPAddress(address='2001:db8::4/64', vrf=vrfs[2], interface=interfaces[5], status=IPAddressStatusChoices.STATUS_DEPRECATED, role=IPAddressRoleChoices.ROLE_SECONDARY, dns_name='ipaddress-d'),
+            IPAddress(address='2001:db8::1/65', vrf=None, interface=None, status=IPAddressStatusChoices.STATUS_ACTIVE),
 
 
         )
         )
         IPAddress.objects.bulk_create(ipaddresses)
         IPAddress.objects.bulk_create(ipaddresses)

+ 47 - 48
netbox/ipam/tests/test_models.py

@@ -15,22 +15,22 @@ class TestAggregate(TestCase):
 
 
         # 25% utilization
         # 25% utilization
         Prefix.objects.bulk_create((
         Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/12')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.16.0.0/12')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.32.0.0/12')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.48.0.0/12')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/12')),
+            Prefix(prefix=netaddr.IPNetwork('10.16.0.0/12')),
+            Prefix(prefix=netaddr.IPNetwork('10.32.0.0/12')),
+            Prefix(prefix=netaddr.IPNetwork('10.48.0.0/12')),
         ))
         ))
         self.assertEqual(aggregate.get_utilization(), 25)
         self.assertEqual(aggregate.get_utilization(), 25)
 
 
         # 50% utilization
         # 50% utilization
         Prefix.objects.bulk_create((
         Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.64.0.0/10')),
+            Prefix(prefix=netaddr.IPNetwork('10.64.0.0/10')),
         ))
         ))
         self.assertEqual(aggregate.get_utilization(), 50)
         self.assertEqual(aggregate.get_utilization(), 50)
 
 
         # 100% utilization
         # 100% utilization
         Prefix.objects.bulk_create((
         Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.128.0.0/9')),
+            Prefix(prefix=netaddr.IPNetwork('10.128.0.0/9')),
         ))
         ))
         self.assertEqual(aggregate.get_utilization(), 100)
         self.assertEqual(aggregate.get_utilization(), 100)
 
 
@@ -39,9 +39,9 @@ class TestPrefix(TestCase):
 
 
     def test_get_duplicates(self):
     def test_get_duplicates(self):
         prefixes = Prefix.objects.bulk_create((
         prefixes = Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('192.0.2.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('192.0.2.0/24')),
         ))
         ))
         duplicate_prefix_pks = [p.pk for p in prefixes[0].get_duplicates()]
         duplicate_prefix_pks = [p.pk for p in prefixes[0].get_duplicates()]
 
 
@@ -54,11 +54,11 @@ class TestPrefix(TestCase):
             VRF(name='VRF 3'),
             VRF(name='VRF 3'),
         ))
         ))
         prefixes = Prefix.objects.bulk_create((
         prefixes = Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24'), vrf=None),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.1.0/24'), vrf=vrfs[0]),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.2.0/24'), vrf=vrfs[1]),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.3.0/24'), vrf=vrfs[2]),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/24'), vrf=None),
+            Prefix(prefix=netaddr.IPNetwork('10.0.1.0/24'), vrf=vrfs[0]),
+            Prefix(prefix=netaddr.IPNetwork('10.0.2.0/24'), vrf=vrfs[1]),
+            Prefix(prefix=netaddr.IPNetwork('10.0.3.0/24'), vrf=vrfs[2]),
         ))
         ))
         child_prefix_pks = {p.pk for p in prefixes[0].get_child_prefixes()}
         child_prefix_pks = {p.pk for p in prefixes[0].get_child_prefixes()}
 
 
@@ -79,13 +79,13 @@ class TestPrefix(TestCase):
             VRF(name='VRF 3'),
             VRF(name='VRF 3'),
         ))
         ))
         parent_prefix = Prefix.objects.create(
         parent_prefix = Prefix.objects.create(
-            family=4, prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER
+            prefix=netaddr.IPNetwork('10.0.0.0/16'), status=PrefixStatusChoices.STATUS_CONTAINER
         )
         )
         ips = IPAddress.objects.bulk_create((
         ips = IPAddress.objects.bulk_create((
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/24'), vrf=None),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.1.1/24'), vrf=vrfs[0]),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.2.1/24'), vrf=vrfs[1]),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.3.1/24'), vrf=vrfs[2]),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.1/24'), vrf=None),
+            IPAddress(address=netaddr.IPNetwork('10.0.1.1/24'), vrf=vrfs[0]),
+            IPAddress(address=netaddr.IPNetwork('10.0.2.1/24'), vrf=vrfs[1]),
+            IPAddress(address=netaddr.IPNetwork('10.0.3.1/24'), vrf=vrfs[2]),
         ))
         ))
         child_ip_pks = {p.pk for p in parent_prefix.get_child_ips()}
         child_ip_pks = {p.pk for p in parent_prefix.get_child_ips()}
 
 
@@ -102,10 +102,10 @@ class TestPrefix(TestCase):
     def test_get_available_prefixes(self):
     def test_get_available_prefixes(self):
 
 
         prefixes = Prefix.objects.bulk_create((
         prefixes = Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')),  # Parent prefix
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/20')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.32.0/20')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.128.0/18')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16')),  # Parent prefix
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/20')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.32.0/20')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.128.0/18')),
         ))
         ))
         missing_prefixes = netaddr.IPSet([
         missing_prefixes = netaddr.IPSet([
             netaddr.IPNetwork('10.0.16.0/20'),
             netaddr.IPNetwork('10.0.16.0/20'),
@@ -119,15 +119,15 @@ class TestPrefix(TestCase):
 
 
     def test_get_available_ips(self):
     def test_get_available_ips(self):
 
 
-        parent_prefix = Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.0.0/28'))
+        parent_prefix = Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.0.0/28'))
         IPAddress.objects.bulk_create((
         IPAddress.objects.bulk_create((
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.3/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.5/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.7/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.9/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.11/26')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.13/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.1/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.3/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.5/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.7/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.9/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.11/26')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.13/26')),
         ))
         ))
         missing_ips = netaddr.IPSet([
         missing_ips = netaddr.IPSet([
             '10.0.0.2/32',
             '10.0.0.2/32',
@@ -145,40 +145,39 @@ class TestPrefix(TestCase):
     def test_get_first_available_prefix(self):
     def test_get_first_available_prefix(self):
 
 
         prefixes = Prefix.objects.bulk_create((
         prefixes = Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')),  # Parent prefix
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.2.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/16')),  # Parent prefix
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.1.0/24')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.2.0/24')),
         ))
         ))
         self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.3.0/24'))
         self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.3.0/24'))
 
 
-        Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.3.0/24'))
+        Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.3.0/24'))
         self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.4.0/22'))
         self.assertEqual(prefixes[0].get_first_available_prefix(), netaddr.IPNetwork('10.0.4.0/22'))
 
 
     def test_get_first_available_ip(self):
     def test_get_first_available_ip(self):
 
 
-        parent_prefix = Prefix.objects.create(family=4, prefix=netaddr.IPNetwork('10.0.0.0/24'))
+        parent_prefix = Prefix.objects.create(prefix=netaddr.IPNetwork('10.0.0.0/24'))
         IPAddress.objects.bulk_create((
         IPAddress.objects.bulk_create((
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.1/24')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.2/24')),
-            IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.3/24')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.1/24')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.2/24')),
+            IPAddress(address=netaddr.IPNetwork('10.0.0.3/24')),
         ))
         ))
         self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.4/24')
         self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.4/24')
 
 
-        IPAddress.objects.create(family=4, address=netaddr.IPNetwork('10.0.0.4/24'))
+        IPAddress.objects.create(address=netaddr.IPNetwork('10.0.0.4/24'))
         self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.5/24')
         self.assertEqual(parent_prefix.get_first_available_ip(), '10.0.0.5/24')
 
 
     def test_get_utilization(self):
     def test_get_utilization(self):
 
 
         # Container Prefix
         # Container Prefix
         prefix = Prefix.objects.create(
         prefix = Prefix.objects.create(
-            family=4,
             prefix=netaddr.IPNetwork('10.0.0.0/24'),
             prefix=netaddr.IPNetwork('10.0.0.0/24'),
             status=PrefixStatusChoices.STATUS_CONTAINER
             status=PrefixStatusChoices.STATUS_CONTAINER
         )
         )
         Prefix.objects.bulk_create((
         Prefix.objects.bulk_create((
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.0/26')),
-            Prefix(family=4, prefix=netaddr.IPNetwork('10.0.0.128/26')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.0/26')),
+            Prefix(prefix=netaddr.IPNetwork('10.0.0.128/26')),
         ))
         ))
         self.assertEqual(prefix.get_utilization(), 50)
         self.assertEqual(prefix.get_utilization(), 50)
 
 
@@ -187,7 +186,7 @@ class TestPrefix(TestCase):
         prefix.save()
         prefix.save()
         IPAddress.objects.bulk_create(
         IPAddress.objects.bulk_create(
             # Create 32 IPAddresses within the Prefix
             # Create 32 IPAddresses within the Prefix
-            [IPAddress(family=4, address=netaddr.IPNetwork('10.0.0.{}/24'.format(i))) for i in range(1, 33)]
+            [IPAddress(address=netaddr.IPNetwork('10.0.0.{}/24'.format(i))) for i in range(1, 33)]
         )
         )
         self.assertEqual(prefix.get_utilization(), 12)  # ~= 12%
         self.assertEqual(prefix.get_utilization(), 12)  # ~= 12%
 
 
@@ -224,9 +223,9 @@ class TestIPAddress(TestCase):
 
 
     def test_get_duplicates(self):
     def test_get_duplicates(self):
         ips = IPAddress.objects.bulk_create((
         ips = IPAddress.objects.bulk_create((
-            IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')),
-            IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')),
-            IPAddress(family=4, address=netaddr.IPNetwork('192.0.2.1/24')),
+            IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')),
+            IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')),
+            IPAddress(address=netaddr.IPNetwork('192.0.2.1/24')),
         ))
         ))
         duplicate_ip_pks = [p.pk for p in ips[0].get_duplicates()]
         duplicate_ip_pks = [p.pk for p in ips[0].get_duplicates()]
 
 

+ 81 - 81
netbox/ipam/tests/test_ordering.py

@@ -42,45 +42,45 @@ class PrefixOrderingTestCase(OrderingTestBase):
 
 
         # Setup Prefixes
         # Setup Prefixes
         prefixes = (
         prefixes = (
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.4.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.5.0/24')),
-
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/8')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.4.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.4.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.2.4.0/24')),
-
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/12')),
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.16.4.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.2.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.3.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, prefix=netaddr.IPNetwork('172.17.4.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.4.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.5.0/24')),
+
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/8')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.4.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.4.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.2.4.0/24')),
+
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/12')),
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.16.4.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.2.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.3.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfb, prefix=netaddr.IPNetwork('172.17.4.0/24')),
         )
         )
 
 
         Prefix.objects.bulk_create(prefixes)
         Prefix.objects.bulk_create(prefixes)
@@ -109,15 +109,15 @@ class PrefixOrderingTestCase(OrderingTestBase):
 
 
         # Setup Prefixes
         # Setup Prefixes
         prefixes = [
         prefixes = [
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('10.0.0.0/8')),
-            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, family=4, prefix=netaddr.IPNetwork('10.0.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('10.1.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, family=4, prefix=netaddr.IPNetwork('192.168.0.0/16')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.0.1.0/25')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.0.0/24')),
-            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, prefix=netaddr.IPNetwork('10.1.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('10.0.0.0/8')),
+            Prefix(status=PrefixStatusChoices.STATUS_CONTAINER, vrf=None, prefix=netaddr.IPNetwork('10.0.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('10.1.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=None, prefix=netaddr.IPNetwork('192.168.0.0/16')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.0.1.0/25')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.0.0/24')),
+            Prefix(status=PrefixStatusChoices.STATUS_ACTIVE, vrf=vrfa, prefix=netaddr.IPNetwork('10.1.1.0/24')),
         ]
         ]
         Prefix.objects.bulk_create(prefixes)
         Prefix.objects.bulk_create(prefixes)
 
 
@@ -136,39 +136,39 @@ class IPAddressOrderingTestCase(OrderingTestBase):
 
 
         # Setup Addresses
         # Setup Addresses
         addresses = (
         addresses = (
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.0.4.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.1.4.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, family=4, address=netaddr.IPNetwork('10.2.4.1/24')),
-
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.16.4.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, family=4, address=netaddr.IPNetwork('172.17.4.1/24')),
-
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.0.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.1.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.2.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.3.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.4.1/24')),
-            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, family=4, address=netaddr.IPNetwork('192.168.5.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.0.4.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.1.4.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfa, address=netaddr.IPNetwork('10.2.4.1/24')),
+
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.16.4.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=vrfb, address=netaddr.IPNetwork('172.17.4.1/24')),
+
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.0.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.1.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.2.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.3.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.4.1/24')),
+            IPAddress(status=IPAddressStatusChoices.STATUS_ACTIVE, vrf=None, address=netaddr.IPNetwork('192.168.5.1/24')),
         )
         )
         IPAddress.objects.bulk_create(addresses)
         IPAddress.objects.bulk_create(addresses)
 
 

+ 9 - 10
netbox/ipam/tests/test_views.py

@@ -82,13 +82,12 @@ class AggregateTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         RIR.objects.bulk_create(rirs)
         RIR.objects.bulk_create(rirs)
 
 
         Aggregate.objects.bulk_create([
         Aggregate.objects.bulk_create([
-            Aggregate(family=4, prefix=IPNetwork('10.1.0.0/16'), rir=rirs[0]),
-            Aggregate(family=4, prefix=IPNetwork('10.2.0.0/16'), rir=rirs[0]),
-            Aggregate(family=4, prefix=IPNetwork('10.3.0.0/16'), rir=rirs[0]),
+            Aggregate(prefix=IPNetwork('10.1.0.0/16'), rir=rirs[0]),
+            Aggregate(prefix=IPNetwork('10.2.0.0/16'), rir=rirs[0]),
+            Aggregate(prefix=IPNetwork('10.3.0.0/16'), rir=rirs[0]),
         ])
         ])
 
 
         cls.form_data = {
         cls.form_data = {
-            'family': 4,
             'prefix': IPNetwork('10.99.0.0/16'),
             'prefix': IPNetwork('10.99.0.0/16'),
             'rir': rirs[1].pk,
             'rir': rirs[1].pk,
             'date_added': datetime.date(2020, 1, 1),
             'date_added': datetime.date(2020, 1, 1),
@@ -161,9 +160,9 @@ class PrefixTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         )
         )
 
 
         Prefix.objects.bulk_create([
         Prefix.objects.bulk_create([
-            Prefix(family=4, prefix=IPNetwork('10.1.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
-            Prefix(family=4, prefix=IPNetwork('10.2.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
-            Prefix(family=4, prefix=IPNetwork('10.3.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
+            Prefix(prefix=IPNetwork('10.1.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
+            Prefix(prefix=IPNetwork('10.2.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
+            Prefix(prefix=IPNetwork('10.3.0.0/16'), vrf=vrfs[0], site=sites[0], role=roles[0]),
         ])
         ])
 
 
         cls.form_data = {
         cls.form_data = {
@@ -209,9 +208,9 @@ class IPAddressTestCase(ViewTestCases.PrimaryObjectViewTestCase):
         )
         )
 
 
         IPAddress.objects.bulk_create([
         IPAddress.objects.bulk_create([
-            IPAddress(family=4, address=IPNetwork('192.0.2.1/24'), vrf=vrfs[0]),
-            IPAddress(family=4, address=IPNetwork('192.0.2.2/24'), vrf=vrfs[0]),
-            IPAddress(family=4, address=IPNetwork('192.0.2.3/24'), vrf=vrfs[0]),
+            IPAddress(address=IPNetwork('192.0.2.1/24'), vrf=vrfs[0]),
+            IPAddress(address=IPNetwork('192.0.2.2/24'), vrf=vrfs[0]),
+            IPAddress(address=IPNetwork('192.0.2.3/24'), vrf=vrfs[0]),
         ])
         ])
 
 
         cls.form_data = {
         cls.form_data = {

+ 1 - 1
netbox/ipam/views.py

@@ -207,7 +207,7 @@ class RIRListView(PermissionRequiredMixin, ObjectListView):
                 'deprecated': 0,
                 'deprecated': 0,
                 'available': 0,
                 'available': 0,
             }
             }
-            aggregate_list = Aggregate.objects.filter(family=family, rir=rir)
+            aggregate_list = Aggregate.objects.filter(prefix__family=family, rir=rir)
             for aggregate in aggregate_list:
             for aggregate in aggregate_list:
 
 
                 queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))
                 queryset = Prefix.objects.filter(prefix__net_contained_or_equal=str(aggregate.prefix))

+ 1 - 1
netbox/templates/ipam/aggregate.html

@@ -64,7 +64,7 @@
             <table class="table table-hover panel-body attr-table">
             <table class="table table-hover panel-body attr-table">
                 <tr>
                 <tr>
                     <td>Family</td>
                     <td>Family</td>
-                    <td>{{ aggregate.get_family_display }}</td>
+                    <td>IPv{{ aggregate.family }}</td>
                 </tr>
                 </tr>
                 <tr>
                 <tr>
                     <td>RIR</td>
                     <td>RIR</td>

+ 1 - 1
netbox/templates/ipam/ipaddress.html

@@ -65,7 +65,7 @@
             <table class="table table-hover panel-body attr-table">
             <table class="table table-hover panel-body attr-table">
                 <tr>
                 <tr>
                     <td>Family</td>
                     <td>Family</td>
-                    <td>{{ ipaddress.get_family_display }}</td>
+                    <td>IPv{{ ipaddress.family }}</td>
                 </tr>
                 </tr>
                 <tr>
                 <tr>
                     <td>VRF</td>
                     <td>VRF</td>

+ 1 - 1
netbox/templates/ipam/prefix.html

@@ -85,7 +85,7 @@
                 <table class="table table-hover panel-body attr-table">
                 <table class="table table-hover panel-body attr-table">
                     <tr>
                     <tr>
                         <td>Family</td>
                         <td>Family</td>
-                        <td>{{ prefix.get_family_display }}</td>
+                        <td>IPv{{ prefix.family }}</td>
                     </tr>
                     </tr>
                     <tr>
                     <tr>
                         <td>VRF</td>
                         <td>VRF</td>

+ 2 - 2
netbox/templates/utilities/obj_list.html

@@ -51,12 +51,12 @@
                 <div class="pull-left noprint">
                 <div class="pull-left noprint">
                     {% block bulk_buttons %}{% endblock %}
                     {% block bulk_buttons %}{% endblock %}
                     {% if bulk_edit_url and permissions.change %}
                     {% if bulk_edit_url and permissions.change %}
-                        <button type="submit" name="_edit" formaction="{% url bulk_edit_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-warning btn-sm">
+                        <button type="submit" name="_edit" formaction="{% url bulk_edit_url %}" class="btn btn-warning btn-sm">
                             <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit Selected
                             <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Edit Selected
                         </button>
                         </button>
                     {% endif %}
                     {% endif %}
                     {% if bulk_delete_url and permissions.delete %}
                     {% if bulk_delete_url and permissions.delete %}
-                        <button type="submit" name="_delete" formaction="{% url bulk_delete_url %}{% if request.GET %}?{{ request.GET.urlencode }}{% endif %}" class="btn btn-danger btn-sm">
+                        <button type="submit" name="_delete" formaction="{% url bulk_delete_url %}" class="btn btn-danger btn-sm">
                             <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete Selected
                             <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> Delete Selected
                         </button>
                         </button>
                     {% endif %}
                     {% endif %}

+ 1 - 5
netbox/utilities/views.py

@@ -634,7 +634,7 @@ class BulkEditView(GetReturnURLMixin, View):
             post_data['pk'] = [obj.pk for obj in self.filterset(request.GET, model.objects.only('pk')).qs]
             post_data['pk'] = [obj.pk for obj in self.filterset(request.GET, model.objects.only('pk')).qs]
 
 
         if '_apply' in request.POST:
         if '_apply' in request.POST:
-            form = self.form(model, request.POST, initial=request.GET)
+            form = self.form(model, request.POST)
             if form.is_valid():
             if form.is_valid():
 
 
                 custom_fields = form.custom_fields if hasattr(form, 'custom_fields') else []
                 custom_fields = form.custom_fields if hasattr(form, 'custom_fields') else []
@@ -718,10 +718,6 @@ class BulkEditView(GetReturnURLMixin, View):
         else:
         else:
             # Pass the PK list as initial data to avoid binding the form
             # Pass the PK list as initial data to avoid binding the form
             initial_data = querydict_to_dict(post_data)
             initial_data = querydict_to_dict(post_data)
-
-            # Append any normal initial data (passed as GET parameters)
-            initial_data.update(request.GET)
-
             form = self.form(model, initial=initial_data)
             form = self.form(model, initial=initial_data)
 
 
         # Retrieve objects being edited
         # Retrieve objects being edited

+ 2 - 2
netbox/virtualization/forms.py

@@ -408,7 +408,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
                 ip_choices = [(None, '---------')]
                 ip_choices = [(None, '---------')]
                 # Collect interface IPs
                 # Collect interface IPs
                 interface_ips = IPAddress.objects.prefetch_related('interface').filter(
                 interface_ips = IPAddress.objects.prefetch_related('interface').filter(
-                    family=family, interface__virtual_machine=self.instance
+                    address__family=family, interface__virtual_machine=self.instance
                 )
                 )
                 if interface_ips:
                 if interface_ips:
                     ip_choices.append(
                     ip_choices.append(
@@ -418,7 +418,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldModelForm):
                     )
                     )
                 # Collect NAT IPs
                 # Collect NAT IPs
                 nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
                 nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
-                    family=family, nat_inside__interface__virtual_machine=self.instance
+                    address__family=family, nat_inside__interface__virtual_machine=self.instance
                 )
                 )
                 if nat_ips:
                 if nat_ips:
                     ip_choices.append(
                     ip_choices.append(