mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-10 22:02:17 -06:00
Compare commits
6 Commits
f371004809
...
5a24f99c9d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a24f99c9d | ||
|
|
9318c91405 | ||
|
|
5c6aaf2388 | ||
|
|
265f375595 | ||
|
|
2699149016 | ||
|
|
60fce84c96 |
@@ -5,7 +5,7 @@
|
||||
<a href="https://github.com/netbox-community/netbox/blob/main/LICENSE.txt"><img src="https://img.shields.io/badge/license-Apache_2.0-blue.svg" alt="License" /></a>
|
||||
<a href="https://github.com/netbox-community/netbox/graphs/contributors"><img src="https://img.shields.io/github/contributors/netbox-community/netbox?color=blue" alt="Contributors" /></a>
|
||||
<a href="https://github.com/netbox-community/netbox/stargazers"><img src="https://img.shields.io/github/stars/netbox-community/netbox?style=flat" alt="GitHub stars" /></a>
|
||||
<a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-15-blue" alt="Languages supported" /></a>
|
||||
<a href="https://explore.transifex.com/netbox-community/netbox/"><img src="https://img.shields.io/badge/languages-16-blue" alt="Languages supported" /></a>
|
||||
<a href="https://github.com/netbox-community/netbox/actions/workflows/ci.yml"><img src="https://github.com/netbox-community/netbox/actions/workflows/ci.yml/badge.svg" alt="CI status" /></a>
|
||||
<p>
|
||||
<strong><a href="https://netboxlabs.com/community/">NetBox Community</a></strong> |
|
||||
|
||||
@@ -449,7 +449,14 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
||||
return model.objects.filter(pk__in=value)
|
||||
return value
|
||||
|
||||
def to_form_field(self, set_initial=True, enforce_required=True, enforce_visibility=True, for_csv_import=False):
|
||||
def to_form_field(
|
||||
self,
|
||||
set_initial=True,
|
||||
enforce_required=True,
|
||||
enforce_visibility=True,
|
||||
for_csv_import=False,
|
||||
for_filterset_form=False,
|
||||
):
|
||||
"""
|
||||
Return a form field suitable for setting a CustomField's value for an object.
|
||||
|
||||
@@ -457,6 +464,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
||||
enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
|
||||
enforce_visibility: Honor the value of CustomField.ui_visible. Set to False for filtering.
|
||||
for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
|
||||
for_filterset_form: Return a form field suitable for use in a FilterSet form.
|
||||
"""
|
||||
initial = self.default if set_initial else None
|
||||
required = self.required if enforce_required else False
|
||||
@@ -519,7 +527,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
|
||||
field_class = CSVMultipleChoiceField
|
||||
field = field_class(choices=choices, required=required, initial=initial)
|
||||
else:
|
||||
if self.type == CustomFieldTypeChoices.TYPE_SELECT:
|
||||
if self.type == CustomFieldTypeChoices.TYPE_SELECT and not for_filterset_form:
|
||||
field_class = DynamicChoiceField
|
||||
widget_class = APISelect
|
||||
else:
|
||||
|
||||
@@ -910,13 +910,13 @@ class IPAddress(ContactsMixin, PrimaryModel):
|
||||
})
|
||||
|
||||
# Disallow the creation of IPAddresses within an IPRange with mark_populated=True
|
||||
parent_range = IPRange.objects.filter(
|
||||
parent_range_qs = IPRange.objects.filter(
|
||||
start_address__lte=self.address,
|
||||
end_address__gte=self.address,
|
||||
vrf=self.vrf,
|
||||
mark_populated=True
|
||||
).first()
|
||||
if parent_range:
|
||||
)
|
||||
if not self.pk and (parent_range := parent_range_qs.first()):
|
||||
raise ValidationError({
|
||||
'address': _(
|
||||
"Cannot create IP address {ip} inside range {range}."
|
||||
|
||||
@@ -1071,14 +1071,17 @@ class VLANGroupTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'name': 'VLAN Group 4',
|
||||
'slug': 'vlan-group-4',
|
||||
'vid_ranges': [[1, 4094]]
|
||||
},
|
||||
{
|
||||
'name': 'VLAN Group 5',
|
||||
'slug': 'vlan-group-5',
|
||||
'vid_ranges': [[1, 4094]]
|
||||
},
|
||||
{
|
||||
'name': 'VLAN Group 6',
|
||||
'slug': 'vlan-group-6',
|
||||
'vid_ranges': [[1, 4094]]
|
||||
},
|
||||
]
|
||||
bulk_update_data = {
|
||||
|
||||
@@ -205,4 +205,6 @@ class NetBoxModelFilterSetForm(CustomFieldsMixin, SavedFiltersMixin, forms.Form)
|
||||
)
|
||||
|
||||
def _get_form_field(self, customfield):
|
||||
return customfield.to_form_field(set_initial=False, enforce_required=False, enforce_visibility=False)
|
||||
return customfield.to_form_field(
|
||||
set_initial=False, enforce_required=False, enforce_visibility=False, for_filterset_form=True
|
||||
)
|
||||
|
||||
@@ -827,6 +827,7 @@ LANGUAGES = (
|
||||
('fr', _('French')),
|
||||
('it', _('Italian')),
|
||||
('ja', _('Japanese')),
|
||||
('lv', _('Latvian')),
|
||||
('nl', _('Dutch')),
|
||||
('pl', _('Polish')),
|
||||
('pt', _('Portuguese')),
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-12-13 05:01+0000\n"
|
||||
"POT-Creation-Date: 2025-12-18 05:03+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@@ -9267,113 +9267,113 @@ msgstr ""
|
||||
msgid "Filter must be defined as a dictionary mapping attributes to values."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:488
|
||||
#: netbox/extras/models/customfields.py:496
|
||||
msgid "True"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:489
|
||||
#: netbox/extras/models/customfields.py:497
|
||||
msgid "False"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:542
|
||||
#: netbox/extras/models/customfields.py:590
|
||||
#: netbox/extras/models/customfields.py:550
|
||||
#: netbox/extras/models/customfields.py:598
|
||||
#, python-brace-format
|
||||
msgid "Values must match this regex: <code>{regex}</code>"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:692
|
||||
#: netbox/extras/models/customfields.py:699
|
||||
#: netbox/extras/models/customfields.py:700
|
||||
#: netbox/extras/models/customfields.py:707
|
||||
msgid "Value must be a string."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:694
|
||||
#: netbox/extras/models/customfields.py:701
|
||||
#: netbox/extras/models/customfields.py:702
|
||||
#: netbox/extras/models/customfields.py:709
|
||||
#, python-brace-format
|
||||
msgid "Value must match regex '{regex}'"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:706
|
||||
#: netbox/extras/models/customfields.py:714
|
||||
msgid "Value must be an integer."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:709
|
||||
#: netbox/extras/models/customfields.py:724
|
||||
#: netbox/extras/models/customfields.py:717
|
||||
#: netbox/extras/models/customfields.py:732
|
||||
#, python-brace-format
|
||||
msgid "Value must be at least {minimum}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:713
|
||||
#: netbox/extras/models/customfields.py:728
|
||||
#: netbox/extras/models/customfields.py:721
|
||||
#: netbox/extras/models/customfields.py:736
|
||||
#, python-brace-format
|
||||
msgid "Value must not exceed {maximum}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:721
|
||||
#: netbox/extras/models/customfields.py:729
|
||||
msgid "Value must be a decimal."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:733
|
||||
#: netbox/extras/models/customfields.py:741
|
||||
msgid "Value must be true or false."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:741
|
||||
#: netbox/extras/models/customfields.py:749
|
||||
msgid "Date values must be in ISO 8601 format (YYYY-MM-DD)."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:750
|
||||
#: netbox/extras/models/customfields.py:758
|
||||
msgid "Date and time values must be in ISO 8601 format (YYYY-MM-DD HH:MM:SS)."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:757
|
||||
#: netbox/extras/models/customfields.py:765
|
||||
#, python-brace-format
|
||||
msgid "Invalid choice ({value}) for choice set {choiceset}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:767
|
||||
#: netbox/extras/models/customfields.py:775
|
||||
#, python-brace-format
|
||||
msgid "Invalid choice(s) ({value}) for choice set {choiceset}."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:776
|
||||
#: netbox/extras/models/customfields.py:784
|
||||
#, python-brace-format
|
||||
msgid "Value must be an object ID, not {type}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:782
|
||||
#: netbox/extras/models/customfields.py:790
|
||||
#, python-brace-format
|
||||
msgid "Value must be a list of object IDs, not {type}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:786
|
||||
#: netbox/extras/models/customfields.py:794
|
||||
#, python-brace-format
|
||||
msgid "Found invalid object ID: {id}"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:789
|
||||
#: netbox/extras/models/customfields.py:797
|
||||
msgid "Required field cannot be empty."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:809
|
||||
#: netbox/extras/models/customfields.py:817
|
||||
msgid "Base set of predefined choices (optional)"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:821
|
||||
#: netbox/extras/models/customfields.py:829
|
||||
msgid "Choices are automatically ordered alphabetically"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:828
|
||||
#: netbox/extras/models/customfields.py:836
|
||||
msgid "custom field choice set"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:829
|
||||
#: netbox/extras/models/customfields.py:837
|
||||
msgid "custom field choice sets"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:871
|
||||
#: netbox/extras/models/customfields.py:879
|
||||
msgid "Must define base or extra choices."
|
||||
msgstr ""
|
||||
|
||||
#: netbox/extras/models/customfields.py:895
|
||||
#: netbox/extras/models/customfields.py:903
|
||||
#, python-brace-format
|
||||
msgid ""
|
||||
"Cannot remove choice {choice} as there are {model} objects which reference "
|
||||
@@ -12523,30 +12523,34 @@ msgid "Japanese"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:830
|
||||
msgid "Dutch"
|
||||
msgid "Latvian"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:831
|
||||
msgid "Polish"
|
||||
msgid "Dutch"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:832
|
||||
msgid "Portuguese"
|
||||
msgid "Polish"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:833
|
||||
msgid "Russian"
|
||||
msgid "Portuguese"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:834
|
||||
msgid "Turkish"
|
||||
msgid "Russian"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:835
|
||||
msgid "Ukrainian"
|
||||
msgid "Turkish"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:836
|
||||
msgid "Ukrainian"
|
||||
msgstr ""
|
||||
|
||||
#: netbox/netbox/settings.py:837
|
||||
msgid "Chinese"
|
||||
msgstr ""
|
||||
|
||||
|
||||
16393
netbox/translations/lv/LC_MESSAGES/django.po
Normal file
16393
netbox/translations/lv/LC_MESSAGES/django.po
Normal file
File diff suppressed because it is too large
Load Diff
@@ -141,8 +141,8 @@ class ModelTestCase(TestCase):
|
||||
elif value and type(field) is GenericForeignKey:
|
||||
model_dict[key] = value.pk
|
||||
|
||||
# Handle API output
|
||||
elif api:
|
||||
|
||||
# Replace ContentType numeric IDs with <app_label>.<model>
|
||||
if type(getattr(instance, key)) in (ContentType, ObjectType):
|
||||
object_type = ObjectType.objects.get(pk=value)
|
||||
@@ -152,9 +152,13 @@ class ModelTestCase(TestCase):
|
||||
elif type(value) is IPNetwork:
|
||||
model_dict[key] = str(value)
|
||||
|
||||
else:
|
||||
field = instance._meta.get_field(key)
|
||||
# Normalize arrays of numeric ranges (e.g. VLAN IDs or port ranges).
|
||||
# DB uses canonical half-open [lo, hi) via NumericRange; API uses inclusive [lo, hi].
|
||||
# Convert to inclusive pairs for stable API comparisons.
|
||||
elif type(field) is ArrayField and issubclass(type(field.base_field), RangeField):
|
||||
model_dict[key] = [[r.lower, r.upper - 1] for r in value]
|
||||
|
||||
else:
|
||||
# Convert ArrayFields to CSV strings
|
||||
if type(field) is ArrayField:
|
||||
if getattr(field.base_field, 'choices', None):
|
||||
|
||||
Reference in New Issue
Block a user