From 6b19f15a7b605ff87aefd6905a930a452ceffb9b Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Tue, 9 May 2023 22:19:13 +0530 Subject: [PATCH 1/3] Moves related ips to a tab (#12502) * moves related ips to a tab #12233 * Refactor IP address templates to use a base template --------- Co-authored-by: jeremystretch --- netbox/ipam/models/ip.py | 8 ++++++ netbox/ipam/views.py | 28 ++++++++++++------- netbox/templates/ipam/ipaddress.html | 8 ------ netbox/templates/ipam/ipaddress/base.html | 8 ++++++ .../ipam/ipaddress/ip_addresses.html | 19 +++++++++++++ 5 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 netbox/templates/ipam/ipaddress/base.html create mode 100644 netbox/templates/ipam/ipaddress/ip_addresses.html diff --git a/netbox/ipam/models/ip.py b/netbox/ipam/models/ip.py index 28901ab8e..015f9220c 100644 --- a/netbox/ipam/models/ip.py +++ b/netbox/ipam/models/ip.py @@ -783,6 +783,14 @@ class IPAddress(PrimaryModel): if available_ips: return next(iter(available_ips)) + def get_related_ips(self): + """ + Return all IPAddresses belonging to the same VRF. + """ + return IPAddress.objects.exclude(address=str(self.address)).filter( + vrf=self.vrf, address__net_contained_or_equal=str(self.address) + ) + def clean(self): super().clean() diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 93d0dc8bb..6b19b502d 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -755,19 +755,9 @@ class IPAddressView(generic.ObjectView): # Limit to a maximum of 10 duplicates displayed here duplicate_ips_table = tables.IPAddressTable(duplicate_ips[:10], orderable=False) - # Related IP table - related_ips = IPAddress.objects.restrict(request.user, 'view').exclude( - address=str(instance.address) - ).filter( - vrf=instance.vrf, address__net_contained_or_equal=str(instance.address) - ) - related_ips_table = tables.IPAddressTable(related_ips, orderable=False) - related_ips_table.configure(request) - return { 'parent_prefixes_table': parent_prefixes_table, 'duplicate_ips_table': duplicate_ips_table, - 'related_ips_table': related_ips_table, } @@ -872,6 +862,24 @@ class IPAddressBulkDeleteView(generic.BulkDeleteView): table = tables.IPAddressTable +@register_model_view(IPAddress, 'related_ips', path='related-ip-addresses') +class IPAddressRelatedIPsView(generic.ObjectChildrenView): + queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant') + child_model = IPAddress + table = tables.IPAddressTable + filterset = filtersets.IPAddressFilterSet + template_name = 'ipam/ipaddress/ip_addresses.html' + tab = ViewTab( + label=_('Related IPs'), + badge=lambda x: x.get_related_ips().count(), + weight=500, + hide_if_empty=True, + ) + + def get_children(self, request, parent): + return parent.get_related_ips().restrict(request.user, 'view') + + # # VLAN groups # diff --git a/netbox/templates/ipam/ipaddress.html b/netbox/templates/ipam/ipaddress.html index c649f1dad..e58ac736f 100644 --- a/netbox/templates/ipam/ipaddress.html +++ b/netbox/templates/ipam/ipaddress.html @@ -3,13 +3,6 @@ {% load plugins %} {% load render_table from django_tables2 %} -{% block breadcrumbs %} - {{ block.super }} - {% if object.vrf %} - - {% endif %} -{% endblock %} - {% block content %}
@@ -116,7 +109,6 @@ {% if duplicate_ips_table.rows %} {% include 'inc/panel_table.html' with table=duplicate_ips_table heading='Duplicate IPs' panel_class='danger' %} {% endif %} - {% include 'inc/panel_table.html' with table=related_ips_table heading='Related IPs' %}
Services
{{ object.vrf }} + {% endif %} +{% endblock %} diff --git a/netbox/templates/ipam/ipaddress/ip_addresses.html b/netbox/templates/ipam/ipaddress/ip_addresses.html new file mode 100644 index 000000000..7034329aa --- /dev/null +++ b/netbox/templates/ipam/ipaddress/ip_addresses.html @@ -0,0 +1,19 @@ +{% extends 'ipam/ipaddress/base.html' %} +{% load helpers %} + +{% block content %} + {% include 'inc/table_controls_htmx.html' with table_modal="IPAddressTable_config" %} +
+ {% csrf_token %} +
+
+ {% include 'htmx/table.html' %} +
+
+
+{% endblock content %} + +{% block modals %} + {{ block.super }} + {% table_config_form table %} +{% endblock modals %} From 2d0ac213c70b7483f406d63c09945ac69c8ed290 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 10 May 2023 09:39:25 -0400 Subject: [PATCH 2/3] Changelog for #11670, #11900, #12131, #12233, #12286, #12323 --- docs/release-notes/version-3.5.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index 8bdfb1578..b9094a658 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -4,7 +4,13 @@ ### Enhancements +* [#11670](https://github.com/netbox-community/netbox/issues/11670) - Enable setting device type & module type weight via bulk import +* [#11900](https://github.com/netbox-community/netbox/issues/11900) - Add an outline to the reservation markers on rack elevations +* [#12131](https://github.com/netbox-community/netbox/issues/12131) - Show custom field description as an icon tooltip under object views * [#12223](https://github.com/netbox-community/netbox/issues/12223) - Add columns for parent device bay and position to devices list +* [#12233](https://github.com/netbox-community/netbox/issues/12233) - Move related IP addresses table to a separate tab +* [#12286](https://github.com/netbox-community/netbox/issues/12286) - Show height and total weight under device view +* [#12323](https://github.com/netbox-community/netbox/issues/12323) - Add 100GE CXP interface type * [#12498](https://github.com/netbox-community/netbox/issues/12498) - Hide map button if `MAPS_URL` is empty --- From b7f028fba39026ca92f439c2ba64b0dfa587d429 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Wed, 10 May 2023 10:44:01 -0400 Subject: [PATCH 3/3] Fixes #12550: Fix rear port selection widget under front port creation form --- docs/release-notes/version-3.5.md | 4 ++++ netbox/dcim/forms/object_create.py | 1 + netbox/utilities/forms/mixins.py | 8 ++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/release-notes/version-3.5.md b/docs/release-notes/version-3.5.md index b9094a658..36dc97bb9 100644 --- a/docs/release-notes/version-3.5.md +++ b/docs/release-notes/version-3.5.md @@ -13,6 +13,10 @@ * [#12323](https://github.com/netbox-community/netbox/issues/12323) - Add 100GE CXP interface type * [#12498](https://github.com/netbox-community/netbox/issues/12498) - Hide map button if `MAPS_URL` is empty +### Bug Fixes + +* [#12550](https://github.com/netbox-community/netbox/issues/12550) - Fix rear port selection widget under front port creation form + --- ## v3.5.1 (2023-05-05) diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py index 236077421..d4c9e6ec3 100644 --- a/netbox/dcim/forms/object_create.py +++ b/netbox/dcim/forms/object_create.py @@ -242,6 +242,7 @@ class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm): choices=[], label=_('Rear ports'), help_text=_('Select one rear port assignment for each front port being created.'), + widget=forms.SelectMultiple(attrs={'size': 6}) ) # Override fieldsets from FrontPortForm to omit rear_port_position diff --git a/netbox/utilities/forms/mixins.py b/netbox/utilities/forms/mixins.py index dc9c3eb80..7cdb9731e 100644 --- a/netbox/utilities/forms/mixins.py +++ b/netbox/utilities/forms/mixins.py @@ -32,11 +32,11 @@ class BootstrapMixin: elif isinstance(field.widget, forms.CheckboxInput): field.widget.attrs['class'] = f'{css} form-check-input' - elif isinstance(field.widget, forms.SelectMultiple): - if 'size' not in field.widget.attrs: - field.widget.attrs['class'] = f'{css} netbox-static-select' + elif isinstance(field.widget, forms.SelectMultiple) and 'size' in field.widget.attrs: + # Use native Bootstrap class for multi-line