Skip to content

Closes #8069: Generic children view #8070

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 25 additions & 36 deletions netbox/dcim/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,35 +36,24 @@
)


class DeviceComponentsView(generic.ObjectView):
class DeviceComponentsView(generic.ObjectChildrenView):
queryset = Device.objects.all()
model = None
table = None

def get_components(self, request, instance):
return self.model.objects.restrict(request.user, 'view').filter(device=instance)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device=parent)

def get_extra_context(self, request, instance):
components = self.get_components(request, instance)
table = self.table(data=components, user=request.user)
change_perm = f'{self.model._meta.app_label}.change_{self.model._meta.model_name}'
delete_perm = f'{self.model._meta.app_label}.delete_{self.model._meta.model_name}'
if request.user.has_perm(change_perm) or request.user.has_perm(delete_perm):
table.columns.show('pk')
paginate_table(table, request)

return {
'table': table,
'active_tab': f"{self.model._meta.verbose_name_plural.replace(' ', '-')}",
'active_tab': f"{self.child_model._meta.verbose_name_plural.replace(' ', '-')}",
}


class DeviceTypeComponentsView(DeviceComponentsView):
queryset = DeviceType.objects.all()
template_name = 'dcim/devicetype/component_templates.html'

def get_components(self, request, instance):
return self.model.objects.restrict(request.user, 'view').filter(device_type=instance)
def get_children(self, request, parent):
return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)


class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
Expand Down Expand Up @@ -806,42 +795,42 @@ def get_extra_context(self, request, instance):


class DeviceTypeConsolePortsView(DeviceTypeComponentsView):
model = ConsolePortTemplate
child_model = ConsolePortTemplate
table = tables.ConsolePortTemplateTable


class DeviceTypeConsoleServerPortsView(DeviceTypeComponentsView):
model = ConsoleServerPortTemplate
child_model = ConsoleServerPortTemplate
table = tables.ConsoleServerPortTemplateTable


class DeviceTypePowerPortsView(DeviceTypeComponentsView):
model = PowerPortTemplate
child_model = PowerPortTemplate
table = tables.PowerPortTemplateTable


class DeviceTypePowerOutletsView(DeviceTypeComponentsView):
model = PowerOutletTemplate
child_model = PowerOutletTemplate
table = tables.PowerOutletTemplateTable


class DeviceTypeInterfacesView(DeviceTypeComponentsView):
model = InterfaceTemplate
child_model = InterfaceTemplate
table = tables.InterfaceTemplateTable


class DeviceTypeFrontPortsView(DeviceTypeComponentsView):
model = FrontPortTemplate
child_model = FrontPortTemplate
table = tables.FrontPortTemplateTable


class DeviceTypeRearPortsView(DeviceTypeComponentsView):
model = RearPortTemplate
child_model = RearPortTemplate
table = tables.RearPortTemplateTable


class DeviceTypeDeviceBaysView(DeviceTypeComponentsView):
model = DeviceBayTemplate
child_model = DeviceBayTemplate
table = tables.DeviceBayTemplateTable


Expand Down Expand Up @@ -1337,61 +1326,61 @@ def get_extra_context(self, request, instance):


class DeviceConsolePortsView(DeviceComponentsView):
model = ConsolePort
child_model = ConsolePort
table = tables.DeviceConsolePortTable
template_name = 'dcim/device/consoleports.html'


class DeviceConsoleServerPortsView(DeviceComponentsView):
model = ConsoleServerPort
child_model = ConsoleServerPort
table = tables.DeviceConsoleServerPortTable
template_name = 'dcim/device/consoleserverports.html'


class DevicePowerPortsView(DeviceComponentsView):
model = PowerPort
child_model = PowerPort
table = tables.DevicePowerPortTable
template_name = 'dcim/device/powerports.html'


class DevicePowerOutletsView(DeviceComponentsView):
model = PowerOutlet
child_model = PowerOutlet
table = tables.DevicePowerOutletTable
template_name = 'dcim/device/poweroutlets.html'


class DeviceInterfacesView(DeviceComponentsView):
model = Interface
child_model = Interface
table = tables.DeviceInterfaceTable
template_name = 'dcim/device/interfaces.html'

def get_components(self, request, instance):
return instance.vc_interfaces().restrict(request.user, 'view').prefetch_related(
def get_children(self, request, parent):
return parent.vc_interfaces().restrict(request.user, 'view').prefetch_related(
Prefetch('ip_addresses', queryset=IPAddress.objects.restrict(request.user)),
Prefetch('member_interfaces', queryset=Interface.objects.restrict(request.user))
)


class DeviceFrontPortsView(DeviceComponentsView):
model = FrontPort
child_model = FrontPort
table = tables.DeviceFrontPortTable
template_name = 'dcim/device/frontports.html'


class DeviceRearPortsView(DeviceComponentsView):
model = RearPort
child_model = RearPort
table = tables.DeviceRearPortTable
template_name = 'dcim/device/rearports.html'


class DeviceDeviceBaysView(DeviceComponentsView):
model = DeviceBay
child_model = DeviceBay
table = tables.DeviceDeviceBayTable
template_name = 'dcim/device/devicebays.html'


class DeviceInventoryView(DeviceComponentsView):
model = InventoryItem
child_model = InventoryItem
table = tables.DeviceInventoryItemTable
template_name = 'dcim/device/inventory.html'

Expand Down
149 changes: 44 additions & 105 deletions netbox/ipam/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,106 +453,62 @@ def get_extra_context(self, request, instance):
}


class PrefixPrefixesView(generic.ObjectView):
class PrefixPrefixesView(generic.ObjectChildrenView):
queryset = Prefix.objects.all()
child_model = Prefix
table = tables.PrefixTable
template_name = 'ipam/prefix/prefixes.html'

def get_extra_context(self, request, instance):
# Find all child prefixes contained in this prefix
prefix_list = instance.get_child_prefixes().restrict(request.user, 'view').prefetch_related(
'site', 'vlan', 'role',
)
def get_children(self, request, parent):
child_prefixes = parent.get_child_prefixes().restrict(request.user, 'view')

# Return List of requested Prefixes
# Add available prefixes if requested
show_available = bool(request.GET.get('show_available', 'true') == 'true')
show_assigned = bool(request.GET.get('show_assigned', 'true') == 'true')
child_prefixes = add_requested_prefixes(instance.prefix, prefix_list, show_available, show_assigned)

table = tables.PrefixTable(child_prefixes, user=request.user, exclude=('utilization',))
if request.user.has_perm('ipam.change_prefix') or request.user.has_perm('ipam.delete_prefix'):
table.columns.show('pk')
paginate_table(table, request)
child_prefixes = add_requested_prefixes(parent.prefix, child_prefixes, show_available, show_assigned)

bulk_querystring = 'vrf_id={}&within={}'.format(instance.vrf.pk if instance.vrf else '0', instance.prefix)

# Compile permissions list for rendering the object table
permissions = {
'change': request.user.has_perm('ipam.change_prefix'),
'delete': request.user.has_perm('ipam.delete_prefix'),
}
return child_prefixes

def get_extra_context(self, request, instance):
return {
'table': table,
'permissions': permissions,
'bulk_querystring': bulk_querystring,
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&within={instance.prefix}",
'active_tab': 'prefixes',
'first_available_prefix': instance.get_first_available_prefix(),
'show_available': show_available,
'show_assigned': show_assigned,
'show_available': bool(request.GET.get('show_available', 'true') == 'true'),
'show_assigned': bool(request.GET.get('show_assigned', 'true') == 'true'),
}


class PrefixIPRangesView(generic.ObjectView):
class PrefixIPRangesView(generic.ObjectChildrenView):
queryset = Prefix.objects.all()
child_model = IPRange
table = tables.IPRangeTable
template_name = 'ipam/prefix/ip_ranges.html'

def get_extra_context(self, request, instance):
# Find all IPRanges belonging to this Prefix
ip_ranges = instance.get_child_ranges().restrict(request.user, 'view').prefetch_related('vrf')

table = tables.IPRangeTable(ip_ranges, user=request.user)
if request.user.has_perm('ipam.change_iprange') or request.user.has_perm('ipam.delete_iprange'):
table.columns.show('pk')
paginate_table(table, request)

bulk_querystring = 'vrf_id={}&parent={}'.format(instance.vrf.pk if instance.vrf else '0', instance.prefix)

# Compile permissions list for rendering the object table
permissions = {
'change': request.user.has_perm('ipam.change_iprange'),
'delete': request.user.has_perm('ipam.delete_iprange'),
}
def get_children(self, request, parent):
return parent.get_child_ranges().restrict(request.user, 'view')

def get_extra_context(self, request, instance):
return {
'table': table,
'permissions': permissions,
'bulk_querystring': bulk_querystring,
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
'active_tab': 'ip-ranges',
}


class PrefixIPAddressesView(generic.ObjectView):
class PrefixIPAddressesView(generic.ObjectChildrenView):
queryset = Prefix.objects.all()
child_model = IPAddress
table = tables.IPAddressTable
template_name = 'ipam/prefix/ip_addresses.html'

def get_extra_context(self, request, instance):
# Find all IPAddresses belonging to this Prefix
ipaddresses = instance.get_child_ips().restrict(request.user, 'view').prefetch_related('vrf')

# Add available IP addresses to the table if requested
if request.GET.get('show_available', 'true') == 'true':
ipaddresses = add_available_ipaddresses(instance.prefix, ipaddresses, instance.is_pool)

table = tables.IPAddressTable(ipaddresses, user=request.user)
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
table.columns.show('pk')
paginate_table(table, request)

bulk_querystring = 'vrf_id={}&parent={}'.format(instance.vrf.pk if instance.vrf else '0', instance.prefix)

# Compile permissions list for rendering the object table
permissions = {
'change': request.user.has_perm('ipam.change_ipaddress'),
'delete': request.user.has_perm('ipam.delete_ipaddress'),
}
def get_children(self, request, parent):
return parent.get_child_ips().restrict(request.user, 'view')

def get_extra_context(self, request, instance):
return {
'table': table,
'permissions': permissions,
'bulk_querystring': bulk_querystring,
'bulk_querystring': f"vrf_id={instance.vrf.pk if instance.vrf else '0'}&parent={instance.prefix}",
'active_tab': 'ip-addresses',
'first_available_ip': instance.get_first_available_ip(),
'show_available': request.GET.get('show_available', 'true') == 'true',
}


Expand Down Expand Up @@ -600,35 +556,18 @@ class IPRangeView(generic.ObjectView):
queryset = IPRange.objects.all()


class IPRangeIPAddressesView(generic.ObjectView):
class IPRangeIPAddressesView(generic.ObjectChildrenView):
queryset = IPRange.objects.all()
child_model = IPAddress
table = tables.IPAddressTable
template_name = 'ipam/iprange/ip_addresses.html'

def get_extra_context(self, request, instance):
# Find all IPAddresses within this range
ipaddresses = instance.get_child_ips().restrict(request.user, 'view').prefetch_related('vrf')

# Add available IP addresses to the table if requested
# if request.GET.get('show_available', 'true') == 'true':
# ipaddresses = add_available_ipaddresses(instance.prefix, ipaddresses, instance.is_pool)

ip_table = tables.IPAddressTable(ipaddresses)
if request.user.has_perm('ipam.change_ipaddress') or request.user.has_perm('ipam.delete_ipaddress'):
ip_table.columns.show('pk')
paginate_table(ip_table, request)

# Compile permissions list for rendering the object table
permissions = {
'add': request.user.has_perm('ipam.add_ipaddress'),
'change': request.user.has_perm('ipam.change_ipaddress'),
'delete': request.user.has_perm('ipam.delete_ipaddress'),
}
def get_children(self, request, parent):
return parent.get_child_ips().restrict(request.user, 'view')

def get_extra_context(self, request, instance):
return {
'ip_table': ip_table,
'permissions': permissions,
'active_tab': 'ip-addresses',
'show_available': request.GET.get('show_available', 'true') == 'true',
}


Expand Down Expand Up @@ -1016,32 +955,32 @@ def get_extra_context(self, request, instance):
}


class VLANInterfacesView(generic.ObjectView):
class VLANInterfacesView(generic.ObjectChildrenView):
queryset = VLAN.objects.all()
child_model = Interface
table = tables.VLANDevicesTable
template_name = 'ipam/vlan/interfaces.html'

def get_extra_context(self, request, instance):
interfaces = instance.get_interfaces().prefetch_related('device')
members_table = tables.VLANDevicesTable(interfaces)
paginate_table(members_table, request)
def get_children(self, request, parent):
return parent.get_interfaces().restrict(request.user, 'view')

def get_extra_context(self, request, instance):
return {
'members_table': members_table,
'active_tab': 'interfaces',
}


class VLANVMInterfacesView(generic.ObjectView):
class VLANVMInterfacesView(generic.ObjectChildrenView):
queryset = VLAN.objects.all()
child_model = VMInterface
table = tables.VLANVirtualMachinesTable
template_name = 'ipam/vlan/vminterfaces.html'

def get_extra_context(self, request, instance):
interfaces = instance.get_vminterfaces().prefetch_related('virtual_machine')
members_table = tables.VLANVirtualMachinesTable(interfaces)
paginate_table(members_table, request)
def get_children(self, request, parent):
return parent.get_vminterfaces().restrict(request.user, 'view')

def get_extra_context(self, request, instance):
return {
'members_table': members_table,
'active_tab': 'vminterfaces',
}

Expand Down
Loading