Skip to content

Commit b500cec

Browse files
committed
Merge branch 'develop' into 13843-fix-vlangroup-bulk-edit-scope
2 parents d8d930d + b759d69 commit b500cec

File tree

14 files changed

+96
-82
lines changed

14 files changed

+96
-82
lines changed

docs/release-notes/version-3.6.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
## v3.6.3 (FUTURE)
44

5+
### Enhancements
6+
7+
* [#12732](https://github.com/netbox-community/netbox/issues/12732) - Add toggle to hide disconnected interfaces under device view
8+
9+
### Bug Fixes
10+
11+
* [#13506](https://github.com/netbox-community/netbox/issues/13506) - Enable creating a config template which references a data file via the REST API
12+
* [#13666](https://github.com/netbox-community/netbox/issues/13666) - Cleanly handle reports without any test methods defined
13+
* [#13839](https://github.com/netbox-community/netbox/issues/13839) - Restore original text color for HTML code elements
14+
* [#13845](https://github.com/netbox-community/netbox/issues/13845) - Fix `AttributeError` exception when attaching front/rear images to a device type
15+
* [#13871](https://github.com/netbox-community/netbox/issues/13871) - Fix rack filtering for empty location during device bulk import
16+
* [#13891](https://github.com/netbox-community/netbox/issues/13891) - Allow designating an IP address as primary for device/VM while assigning it to an interface
17+
518
---
619

720
## v3.6.2 (2023-09-20)

netbox/dcim/models/devices.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from functools import cached_property
55

66
from django.core.exceptions import ValidationError
7+
from django.core.files.storage import default_storage
78
from django.core.validators import MaxValueValidator, MinValueValidator
89
from django.db import models
910
from django.db.models import F, ProtectedError
@@ -332,10 +333,10 @@ def save(self, *args, **kwargs):
332333
ret = super().save(*args, **kwargs)
333334

334335
# Delete any previously uploaded image files that are no longer in use
335-
if self.front_image != self._original_front_image:
336-
self._original_front_image.delete(save=False)
337-
if self.rear_image != self._original_rear_image:
338-
self._original_rear_image.delete(save=False)
336+
if self._original_front_image and self.front_image != self._original_front_image:
337+
default_storage.delete(self._original_front_image)
338+
if self._original_rear_image and self.rear_image != self._original_rear_image:
339+
default_storage.delete(self._original_rear_image)
339340

340341
return ret
341342

netbox/dcim/tables/devices.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,19 @@ def get_interface_state_attribute(record):
6464
Get interface enabled state as string to attach to <tr/> DOM element.
6565
"""
6666
if record.enabled:
67-
return "enabled"
67+
return 'enabled'
6868
else:
69-
return "disabled"
69+
return 'disabled'
70+
71+
72+
def get_interface_connected_attribute(record):
73+
"""
74+
Get interface disconnected state as string to attach to <tr/> DOM element.
75+
"""
76+
if record.mark_connected or record.cable:
77+
return 'connected'
78+
else:
79+
return 'disconnected'
7080

7181

7282
#
@@ -674,6 +684,7 @@ class Meta(DeviceComponentTable.Meta):
674684
'data-name': lambda record: record.name,
675685
'data-enabled': get_interface_state_attribute,
676686
'data-type': lambda record: record.type,
687+
'data-connected': get_interface_connected_attribute
677688
}
678689

679690

netbox/extras/api/serializers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer
454454
required=False
455455
)
456456
data_file = NestedDataFileSerializer(
457-
read_only=True
457+
required=False
458458
)
459459

460460
class Meta:

netbox/extras/api/views.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,10 @@ def choices(self, request, pk):
8282
data = [
8383
{'id': c[0], 'display': c[1]} for c in page
8484
]
85-
return self.get_paginated_response(data)
85+
else:
86+
data = []
87+
88+
return self.get_paginated_response(data)
8689

8790

8891
#

netbox/extras/reports.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,6 @@ def __init__(self):
106106
'failure': 0,
107107
'log': [],
108108
}
109-
if not test_methods:
110-
raise Exception("A report must contain at least one test method.")
111109
self.test_methods = test_methods
112110

113111
@classproperty
@@ -137,6 +135,13 @@ def filename(self):
137135
def source(self):
138136
return inspect.getsource(self.__class__)
139137

138+
@property
139+
def is_valid(self):
140+
"""
141+
Indicates whether the report can be run.
142+
"""
143+
return bool(self.test_methods)
144+
140145
#
141146
# Logging methods
142147
#

netbox/ipam/forms/model_forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ def clean(self):
354354
})
355355
elif selected_objects:
356356
assigned_object = self.cleaned_data[selected_objects[0]]
357-
if self.instance.pk and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object:
357+
if self.instance.pk and self.instance.assigned_object and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object:
358358
raise ValidationError(
359359
_("Cannot reassign IP address while it is designated as the primary IP for the parent object")
360360
)

netbox/netbox/api/fields.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,13 @@ def validate_empty_values(self, data):
4646
return super().validate_empty_values(data)
4747

4848
def to_representation(self, obj):
49-
if obj == '':
50-
return None
51-
return {
52-
'value': obj,
53-
'label': self._choices[obj],
54-
}
49+
if obj != '':
50+
# Use an empty string in place of the choice label if it cannot be resolved (i.e. because a previously
51+
# configured choice has been removed from FIELD_CHOICES).
52+
return {
53+
'value': obj,
54+
'label': self._choices.get(obj, ''),
55+
}
5556

5657
def to_internal_value(self, data):
5758
if data == '':

netbox/project-static/dist/netbox.js

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

netbox/project-static/dist/netbox.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)