Skip to content

Commit 26fb733

Browse files
committed
Merge main into feature
1 parent 7bbb04d commit 26fb733

File tree

66 files changed

+2310
-1948
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+2310
-1948
lines changed

.github/ISSUE_TEMPLATE/01-feature_request.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ body:
1515
attributes:
1616
label: NetBox version
1717
description: What version of NetBox are you currently running?
18-
placeholder: v4.3.6
18+
placeholder: v4.3.7
1919
validations:
2020
required: true
2121
- type: dropdown

.github/ISSUE_TEMPLATE/02-bug_report.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ body:
2727
attributes:
2828
label: NetBox Version
2929
description: What version of NetBox are you currently running?
30-
placeholder: v4.3.6
30+
placeholder: v4.3.7
3131
validations:
3232
required: true
3333
- type: dropdown

docs/administration/error-reporting.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
### Enabling Error Reporting
66

7-
NetBox supports native integration with [Sentry](https://sentry.io/) for automatic error reporting. To enable this functionality, set `SENTRY_ENABLED` to True and define your unique [data source name (DSN)](https://docs.sentry.io/product/sentry-basics/concepts/dsn-explainer/) in `configuration.py`.
7+
NetBox supports native integration with [Sentry](https://sentry.io/) for automatic error reporting. To enable this functionality, set `SENTRY_ENABLED` to `True` and define your unique [data source name (DSN)](https://docs.sentry.io/product/sentry-basics/concepts/dsn-explainer/) in `configuration.py`.
88

99
```python
1010
SENTRY_ENABLED = True

docs/reference/conditions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ The following condition will evaluate as true:
8989
```
9090

9191
!!! note "Evaluating static choice fields"
92-
Pay close attention when evaluating static choice fields, such as the `status` field above. These fields typically render as a dictionary specifying both the field's raw value (`value`) and its human-friendly label (`label`). be sure to specify on which of these you want to match.
92+
Pay close attention when evaluating static choice fields, such as the `status` field above. These fields typically render as a dictionary specifying both the field's raw value (`value`) and its human-friendly label (`label`). Be sure to specify on which of these you want to match.
9393

9494
## Condition Sets
9595

docs/release-notes/version-4.3.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,29 @@
11
# NetBox v4.3
22

3+
## v4.3.7 (2025-08-26)
4+
5+
### Enhancements
6+
7+
* [#18147](https://github.com/netbox-community/netbox/issues/18147) - Add device & VM interface counts under related objects for VRFs
8+
* [#19990](https://github.com/netbox-community/netbox/issues/19990) - Button to add a missing prerequisite now includes a return URL
9+
* [#20122](https://github.com/netbox-community/netbox/issues/20122) - Improve color contrast of highlighted data under changelog diff view
10+
* [#20131](https://github.com/netbox-community/netbox/issues/20131) - Add object selector for interface to the MAC address edit form
11+
12+
### Bug Fixes
13+
14+
* [#18916](https://github.com/netbox-community/netbox/issues/18916) - Fix dynamic dropdown selection styling for required fields when no selection is made
15+
* [#19645](https://github.com/netbox-community/netbox/issues/19645) - Fix interface selection when adding a cable for a virtual chassis master
16+
* [#19669](https://github.com/netbox-community/netbox/issues/19669) - Restore token authentication support for fetching media assets
17+
* [#19970](https://github.com/netbox-community/netbox/issues/19970) - Device role child device counts should be cumulative
18+
* [#20012](https://github.com/netbox-community/netbox/issues/20012) - Fix support for `empty` filter lookup on custom fields
19+
* [#20043](https://github.com/netbox-community/netbox/issues/20043) - Fix page styling when rack elevations are embedded
20+
* [#20098](https://github.com/netbox-community/netbox/issues/20098) - Fix `AttributeError` exception when assigning tags during bulk import
21+
* [#20120](https://github.com/netbox-community/netbox/issues/20120) - Fix REST API serialization of jobs under `/api/core/background-tasks/`
22+
* [#20157](https://github.com/netbox-community/netbox/issues/20157) - Fix `IntegrityError` exception when a duplicate notification is triggered
23+
* [#20164](https://github.com/netbox-community/netbox/issues/20164) - Fix `ValueError` exception when attempting to add power outlets to devices in bulk
24+
25+
---
26+
327
## v4.3.6 (2025-08-12)
428

529
### Enhancements
@@ -29,6 +53,8 @@
2953
* [#20033](https://github.com/netbox-community/netbox/issues/20033) - Fix `TypeError` exception when bulk deleting bookmarks
3054
* [#20056](https://github.com/netbox-community/netbox/issues/20056) - Fixed missing RF role options in device type schema validation
3155

56+
---
57+
3258
## v4.3.5 (2025-07-29)
3359

3460
### Enhancements
@@ -48,6 +74,8 @@
4874
!!! note "Plugin Developer Advisory"
4975
The fix for bug [#18900](https://github.com/netbox-community/netbox/issues/18900) now raises explicit exceptions when API endpoints attempt to paginate unordered querysets. Plugin maintainers should review their API viewsets to ensure proper queryset ordering is applied before pagination, either by using `.order_by()` on querysets or by setting `ordering` in model Meta classes. Previously silent pagination issues in plugin code will now raise `QuerySetNotOrdered` exceptions and may require updates to maintain compatibility.
5076

77+
---
78+
5179
## v4.3.4 (2025-07-15)
5280

5381
### Enhancements

netbox/core/api/serializers_/tasks.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ class BackgroundTaskSerializer(serializers.Serializer):
1818
description = serializers.CharField()
1919
origin = serializers.CharField()
2020
func_name = serializers.CharField()
21-
args = serializers.ListField(child=serializers.CharField())
22-
kwargs = serializers.DictField()
21+
args = serializers.SerializerMethodField()
22+
kwargs = serializers.SerializerMethodField()
2323
result = serializers.CharField()
2424
timeout = serializers.IntegerField()
2525
result_ttl = serializers.IntegerField()
@@ -42,6 +42,16 @@ class BackgroundTaskSerializer(serializers.Serializer):
4242
is_scheduled = serializers.BooleanField()
4343
is_stopped = serializers.BooleanField()
4444

45+
def get_args(self, obj) -> list:
46+
return [
47+
str(arg) for arg in obj.args
48+
]
49+
50+
def get_kwargs(self, obj) -> dict:
51+
return {
52+
key: str(value) for key, value in obj.kwargs.items()
53+
}
54+
4555
def get_position(self, obj) -> int:
4656
return obj.get_position()
4757

netbox/dcim/api/serializers_/roles.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from rest_framework import serializers
2+
13
from dcim.models import DeviceRole, InventoryItemRole
24
from extras.api.serializers_.configtemplates import ConfigTemplateSerializer
35
from netbox.api.fields import RelatedObjectCountField
@@ -13,10 +15,8 @@
1315
class DeviceRoleSerializer(NestedGroupModelSerializer):
1416
parent = NestedDeviceRoleSerializer(required=False, allow_null=True, default=None)
1517
config_template = ConfigTemplateSerializer(nested=True, required=False, allow_null=True, default=None)
16-
17-
# Related object counts
18-
device_count = RelatedObjectCountField('devices')
19-
virtualmachine_count = RelatedObjectCountField('virtual_machines')
18+
device_count = serializers.IntegerField(read_only=True, default=0)
19+
virtualmachine_count = serializers.IntegerField(read_only=True, default=0)
2020

2121
class Meta:
2222
model = DeviceRole

netbox/dcim/api/views.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,19 @@ class InventoryItemTemplateViewSet(MPTTLockedMixin, NetBoxModelViewSet):
352352
#
353353

354354
class DeviceRoleViewSet(NetBoxModelViewSet):
355-
queryset = DeviceRole.objects.all()
355+
queryset = DeviceRole.objects.add_related_count(
356+
DeviceRole.objects.add_related_count(
357+
DeviceRole.objects.all(),
358+
VirtualMachine,
359+
'role',
360+
'virtualmachine_count',
361+
cumulative=True
362+
),
363+
Device,
364+
'role',
365+
'device_count',
366+
cumulative=True
367+
)
356368
serializer_class = serializers.DeviceRoleSerializer
357369
filterset_class = filtersets.DeviceRoleFilterSet
358370

netbox/dcim/filtersets.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,6 +1918,16 @@ class InterfaceFilterSet(
19181918
PathEndpointFilterSet,
19191919
CommonInterfaceFilterSet
19201920
):
1921+
virtual_chassis_member_or_master = MultiValueCharFilter(
1922+
method='filter_virtual_chassis_member_or_master',
1923+
field_name='name',
1924+
label=_('Virtual Chassis Interfaces for Device when device is master')
1925+
)
1926+
virtual_chassis_member_or_master_id = MultiValueNumberFilter(
1927+
method='filter_virtual_chassis_member_or_master',
1928+
field_name='pk',
1929+
label=_('Virtual Chassis Interfaces for Device when device is master (ID)')
1930+
)
19211931
virtual_chassis_member = MultiValueCharFilter(
19221932
method='filter_virtual_chassis_member',
19231933
field_name='name',
@@ -2028,11 +2038,14 @@ class Meta:
20282038
'cable_id', 'cable_end',
20292039
)
20302040

2031-
def filter_virtual_chassis_member(self, queryset, name, value):
2041+
def filter_virtual_chassis_member_or_master(self, queryset, name, value):
2042+
return self.filter_virtual_chassis_member(queryset, name, value, if_master=True)
2043+
2044+
def filter_virtual_chassis_member(self, queryset, name, value, if_master=False):
20322045
try:
20332046
vc_interface_ids = []
20342047
for device in Device.objects.filter(**{f'{name}__in': value}):
2035-
vc_interface_ids.extend(device.vc_interfaces(if_master=False).values_list('id', flat=True))
2048+
vc_interface_ids.extend(device.vc_interfaces(if_master=if_master).values_list('id', flat=True))
20362049
return queryset.filter(pk__in=vc_interface_ids)
20372050
except Device.DoesNotExist:
20382051
return queryset.none()

netbox/dcim/forms/bulk_create.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,14 @@ class PowerPortBulkCreateForm(
6969

7070

7171
class PowerOutletBulkCreateForm(
72-
form_from_model(PowerOutlet, ['type', 'color', 'feed_leg', 'mark_connected']),
72+
form_from_model(PowerOutlet, ['type', 'status', 'color', 'feed_leg', 'mark_connected']),
7373
DeviceBulkAddComponentForm
7474
):
7575
model = PowerOutlet
76-
field_order = ('name', 'label', 'type', 'feed_leg', 'description', 'tags')
76+
field_order = (
77+
'name', 'label', 'type', 'status', 'color', 'feed_leg', 'mark_connected',
78+
'description', 'tags',
79+
)
7780

7881

7982
class InterfaceBulkCreateForm(

0 commit comments

Comments
 (0)