mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 17:38:37 -06:00
Merge branch 'develop' into 16837-filter-cable-type-empty
This commit is contained in:
commit
f239b2337c
@ -9,7 +9,7 @@ from dcim.choices import *
|
|||||||
from dcim.constants import *
|
from dcim.constants import *
|
||||||
from dcim.models import *
|
from dcim.models import *
|
||||||
from extras.models import ConfigTemplate
|
from extras.models import ConfigTemplate
|
||||||
from ipam.models import VRF
|
from ipam.models import VRF, IPAddress
|
||||||
from netbox.forms import NetBoxModelImportForm
|
from netbox.forms import NetBoxModelImportForm
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.forms.fields import (
|
from utilities.forms.fields import (
|
||||||
@ -1435,9 +1435,33 @@ class VirtualDeviceContextImportForm(NetBoxModelImportForm):
|
|||||||
label=_('Status'),
|
label=_('Status'),
|
||||||
choices=VirtualDeviceContextStatusChoices,
|
choices=VirtualDeviceContextStatusChoices,
|
||||||
)
|
)
|
||||||
|
primary_ip4 = CSVModelChoiceField(
|
||||||
|
label=_('Primary IPv4'),
|
||||||
|
queryset=IPAddress.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='address',
|
||||||
|
help_text=_('IPv4 address with mask, e.g. 1.2.3.4/24')
|
||||||
|
)
|
||||||
|
primary_ip6 = CSVModelChoiceField(
|
||||||
|
label=_('Primary IPv6'),
|
||||||
|
queryset=IPAddress.objects.all(),
|
||||||
|
required=False,
|
||||||
|
to_field_name='address',
|
||||||
|
help_text=_('IPv6 address with prefix length, e.g. 2001:db8::1/64')
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
fields = [
|
fields = [
|
||||||
'name', 'device', 'status', 'tenant', 'identifier', 'comments',
|
'name', 'device', 'status', 'tenant', 'identifier', 'comments', 'primary_ip4', 'primary_ip6',
|
||||||
]
|
]
|
||||||
model = VirtualDeviceContext
|
model = VirtualDeviceContext
|
||||||
|
|
||||||
|
def __init__(self, data=None, *args, **kwargs):
|
||||||
|
super().__init__(data, *args, **kwargs)
|
||||||
|
|
||||||
|
if data:
|
||||||
|
|
||||||
|
# Limit primary_ip4/ip6 querysets by assigned device
|
||||||
|
params = {f"interface__device__{self.fields['device'].to_field_name}": data.get('device')}
|
||||||
|
self.fields['primary_ip4'].queryset = self.fields['primary_ip4'].queryset.filter(**params)
|
||||||
|
self.fields['primary_ip6'].queryset = self.fields['primary_ip6'].queryset.filter(**params)
|
||||||
|
@ -3253,10 +3253,10 @@ class CableEditView(generic.ObjectEditView):
|
|||||||
doesn't currently provide a hook for dynamic class resolution.
|
doesn't currently provide a hook for dynamic class resolution.
|
||||||
"""
|
"""
|
||||||
a_terminations_type = CABLE_TERMINATION_TYPES.get(
|
a_terminations_type = CABLE_TERMINATION_TYPES.get(
|
||||||
request.GET.get('a_terminations_type') or request.POST.get('a_terminations_type')
|
request.POST.get('a_terminations_type') or request.GET.get('a_terminations_type')
|
||||||
)
|
)
|
||||||
b_terminations_type = CABLE_TERMINATION_TYPES.get(
|
b_terminations_type = CABLE_TERMINATION_TYPES.get(
|
||||||
request.GET.get('b_terminations_type') or request.POST.get('b_terminations_type')
|
request.POST.get('b_terminations_type') or request.GET.get('b_terminations_type')
|
||||||
)
|
)
|
||||||
|
|
||||||
if obj.pk:
|
if obj.pk:
|
||||||
|
@ -149,3 +149,7 @@ class ASN(PrimaryModel):
|
|||||||
return f'{self.asn} ({self.asn // 65536}.{self.asn % 65536})'
|
return f'{self.asn} ({self.asn // 65536}.{self.asn % 65536})'
|
||||||
else:
|
else:
|
||||||
return self.asn
|
return self.asn
|
||||||
|
|
||||||
|
@property
|
||||||
|
def prefixed_name(self):
|
||||||
|
return f'AS{self.asn_with_asdot}'
|
||||||
|
@ -19,6 +19,7 @@ class ASNIndex(SearchIndex):
|
|||||||
model = models.ASN
|
model = models.ASN
|
||||||
fields = (
|
fields = (
|
||||||
('asn', 100),
|
('asn', 100),
|
||||||
|
('prefixed_name', 110),
|
||||||
('description', 500),
|
('description', 500),
|
||||||
)
|
)
|
||||||
display_attrs = ('rir', 'tenant', 'description')
|
display_attrs = ('rir', 'tenant', 'description')
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
from users.preferences import UserPreference
|
from users.preferences import UserPreference
|
||||||
|
BIN
netbox/project-static/dist/netbox.css
vendored
BIN
netbox/project-static/dist/netbox.css
vendored
Binary file not shown.
@ -128,6 +128,9 @@ body[data-bs-theme=dark] {
|
|||||||
.footer .text-primary {
|
.footer .text-primary {
|
||||||
color: white !important;
|
color: white !important;
|
||||||
}
|
}
|
||||||
|
.toast {
|
||||||
|
color: var(--#{$prefix}body-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not apply padding to <code> elements inside a <pre>
|
// Do not apply padding to <code> elements inside a <pre>
|
||||||
|
@ -6,9 +6,11 @@
|
|||||||
|
|
||||||
{# Render the field label (if any), except for checkboxes #}
|
{# Render the field label (if any), except for checkboxes #}
|
||||||
{% if label and not field|widget_type == 'checkboxinput' %}
|
{% if label and not field|widget_type == 'checkboxinput' %}
|
||||||
<label for="{{ field.id_for_label }}" class="col-sm-3 col-form-label text-lg-end{% if field.field.required %} required{% endif %}">
|
<div class="col-sm-3 text-lg-end">
|
||||||
{{ label }}
|
<label for="{{ field.id_for_label }}" class="col-form-label d-inline-block{% if field.field.required %} required{% endif %}">
|
||||||
</label>
|
{{ label }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{# Render the field itself #}
|
{# Render the field itself #}
|
||||||
|
Loading…
Reference in New Issue
Block a user