mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-28 11:26:26 -06:00
Merge branch 'netbox-community:develop' into fix_tunnel_types
This commit is contained in:
commit
99c9b53f2f
@ -18,8 +18,17 @@ jobs:
|
||||
NETBOX_CONFIGURATION: netbox.configuration_testing
|
||||
|
||||
steps:
|
||||
- name: Create app token
|
||||
uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: 1076524
|
||||
private-key: ${{ secrets.HOUSEKEEPING_SECRET_KEY }}
|
||||
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ steps.app-token.outputs.token }}
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v5
|
||||
|
@ -10,6 +10,15 @@ Minor releases are published in April, August, and December of each calendar yea
|
||||
|
||||
This page contains a history of all major and minor releases since NetBox v2.0. For more detail on a specific patch release, please see the release notes page for that specific minor release.
|
||||
|
||||
#### [Version 4.1](./version-4.1.md) (September 2024)
|
||||
|
||||
* Circuit Groups ([#7025](https://github.com/netbox-community/netbox/issues/7025))
|
||||
* VLAN Group ID Ranges ([#9627](https://github.com/netbox-community/netbox/issues/9627))
|
||||
* Nested Device Modules ([#10500](https://github.com/netbox-community/netbox/issues/10500))
|
||||
* Rack Types ([#12826](https://github.com/netbox-community/netbox/issues/12826))
|
||||
* Plugins Catalog Integration ([#14731](https://github.com/netbox-community/netbox/issues/14731))
|
||||
* User Notifications ([#15621](https://github.com/netbox-community/netbox/issues/15621))
|
||||
|
||||
#### [Version 4.0](./version-4.0.md) (April 2024)
|
||||
|
||||
* Complete UI Refresh ([#12128](https://github.com/netbox-community/netbox/issues/12128))
|
||||
|
@ -48,6 +48,7 @@ def get_device_description(device):
|
||||
|
||||
Name: <name>
|
||||
Role: <role>
|
||||
Status: <status>
|
||||
Device Type: <manufacturer> <model> (<u_height>)
|
||||
Asset tag: <asset_tag> (if defined)
|
||||
Serial: <serial> (if defined)
|
||||
@ -55,6 +56,7 @@ def get_device_description(device):
|
||||
"""
|
||||
description = f'Name: {device.name}'
|
||||
description += f'\nRole: {device.role}'
|
||||
description += f'\nStatus: {device.get_status_display()}'
|
||||
u_height = f'{floatformat(device.device_type.u_height)}U'
|
||||
description += f'\nDevice Type: {device.device_type.manufacturer.name} {device.device_type.model} ({u_height})'
|
||||
if device.asset_tag:
|
||||
|
@ -1141,12 +1141,14 @@ class ScriptView(BaseScriptView):
|
||||
script_class = self._get_script_class(script)
|
||||
if not script_class:
|
||||
return render(request, 'extras/script.html', {
|
||||
'object': script,
|
||||
'script': script,
|
||||
})
|
||||
|
||||
form = script_class.as_form(initial=normalize_querydict(request.GET))
|
||||
|
||||
return render(request, 'extras/script.html', {
|
||||
'object': script,
|
||||
'script': script,
|
||||
'script_class': script_class,
|
||||
'form': form,
|
||||
@ -1162,6 +1164,7 @@ class ScriptView(BaseScriptView):
|
||||
script_class = self._get_script_class(script)
|
||||
if not script_class:
|
||||
return render(request, 'extras/script.html', {
|
||||
'object': script,
|
||||
'script': script,
|
||||
})
|
||||
|
||||
@ -1186,6 +1189,7 @@ class ScriptView(BaseScriptView):
|
||||
return redirect('extras:script_result', job_pk=job.pk)
|
||||
|
||||
return render(request, 'extras/script.html', {
|
||||
'object': script,
|
||||
'script': script,
|
||||
'script_class': script.python_class(),
|
||||
'form': form,
|
||||
|
@ -76,6 +76,12 @@ class ValidatedModelSerializer(BaseModelSerializer):
|
||||
Extends the built-in ModelSerializer to enforce calling full_clean() on a copy of the associated instance during
|
||||
validation. (DRF does not do this by default; see https://github.com/encode/django-rest-framework/issues/3144)
|
||||
"""
|
||||
|
||||
# Bypass DRF's built-in validation of unique constraints due to DRF bug #9410. Rely instead
|
||||
# on our own custom model validation (below).
|
||||
def get_unique_together_constraints(self, model):
|
||||
return []
|
||||
|
||||
def validate(self, data):
|
||||
|
||||
# Skip validation if we're being used to represent a nested object
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,14 @@ class DataFileLoader(BaseLoader):
|
||||
raise TemplateNotFound(template)
|
||||
|
||||
# Find and pre-fetch referenced templates
|
||||
if referenced_templates := find_referenced_templates(environment.parse(template_source)):
|
||||
if referenced_templates := tuple(find_referenced_templates(environment.parse(template_source))):
|
||||
related_files = DataFile.objects.filter(source=self.data_source)
|
||||
# None indicates the use of dynamic resolution. If dependent files are statically
|
||||
# defined, we can filter by path for optimization.
|
||||
if None not in referenced_templates:
|
||||
related_files = related_files.filter(path__in=referenced_templates)
|
||||
self.cache_templates({
|
||||
df.path: df.data_as_string for df in
|
||||
DataFile.objects.filter(source=self.data_source, path__in=referenced_templates)
|
||||
df.path: df.data_as_string for df in related_files
|
||||
})
|
||||
|
||||
return template_source, template, lambda: True
|
||||
|
Loading…
Reference in New Issue
Block a user