Compare commits

...

19 Commits

Author SHA1 Message Date
Ash Kirby 9eb313b4d7
Merge 10c6862735 into d606cf1b3c 2024-04-22 15:07:07 -05:00
Jeremy Stretch d606cf1b3c Update source translations 2024-04-22 15:50:38 -04:00
Jeremy Stretch 0b0dab42eb PRVB 2024-04-22 12:23:31 -04:00
Jeremy Stretch d115601da3
Merge pull request #15805 from netbox-community/develop
Release v3.7.6
2024-04-22 12:18:27 -04:00
Jeremy Stretch a61e20849b Release v3.7.6 2024-04-22 11:46:03 -04:00
Arthur Hanson 1eca1c3d17
15803 localize help_text (#15804) 2024-04-22 11:42:20 -04:00
transifex-integration[bot] 5d95d49268
Update translations 2024-04-22 11:28:04 -04:00
Jeremy Stretch 6b8bfe9947 Changelog for #14690, #15541, #15588, #15761, #15771, #15790 2024-04-22 11:25:21 -04:00
Jeremy Stretch e87877b6ea Fixes #15771: Show id field as supported on all bulk import forms 2024-04-22 11:08:36 -04:00
Jeremy Stretch ebe504c825 Closes #15664: Restore usage of READTHEDOCS env variable 2024-04-22 09:52:03 -04:00
Markku Leiniö b6e38b2ebe
Closes #14690: Pretty-format JSON fields in the config form (#15623)
* Closes #14690: Pretty-format JSON fields in the config form

* Revert changes

* Use our own JSONField for config parameters for pretty editor outputs

* Compare identity instead of equality
2024-04-22 09:25:16 -04:00
Arthur Hanson 90d0104359
15541 Add component selector to InventoryItemTemplate (#15759)
* 15541 make inventoryitemtemplateform match inventoryitemform

* 15541 set tab active
2024-04-22 08:22:53 -04:00
arcticash 10c6862735
Moving the Molex connectors into their own category for better UX - expansion on #12984 2024-03-15 15:55:23 +00:00
Ash Kirby fb646dd915
Merge branch 'netbox-community:develop' into develop 2024-03-15 15:35:29 +00:00
Ash Kirby 6c06d31a80
Merge branch 'netbox-community:develop' into develop 2024-03-11 22:17:04 +00:00
Ash Kirby 2d7e33df3b
Merge branch 'netbox-community:develop' into develop 2024-02-18 20:07:54 +00:00
Ash Kirby f613fe7650
Merge branch 'netbox-community:develop' into develop 2024-02-06 21:58:29 +00:00
arcticash f49dcbe9d4
Adding Molex Micro-Fit connectors to power outlet choices to fix #12984 2024-01-23 21:53:35 +00:00
arcticash ad58d370d2
Adding Molex Micro-Fit connectors to power plug choices to fix #12984 2024-01-23 21:47:10 +00:00
24 changed files with 503 additions and 215 deletions

View File

@ -26,7 +26,7 @@ body:
attributes:
label: NetBox Version
description: What version of NetBox are you currently running?
placeholder: v3.7.5
placeholder: v3.7.6
validations:
required: true
- type: dropdown

View File

@ -14,7 +14,7 @@ body:
attributes:
label: NetBox version
description: What version of NetBox are you currently running?
placeholder: v3.7.5
placeholder: v3.7.6
validations:
required: true
- type: dropdown

View File

@ -61,7 +61,8 @@ django-timezone-field
# A REST API framework for Django projects
# https://www.django-rest-framework.org/community/release-notes/
djangorestframework
# Pinned to 3.14 for NetBox v3.7
djangorestframework<3.15
# Sane and flexible OpenAPI 3 schema generation for Django REST framework.
# https://github.com/tfranzel/drf-spectacular/blob/master/CHANGELOG.rst

View File

@ -2,8 +2,8 @@
{% block site_meta %}
{{ super() }}
{# Disable search indexing unless we're building for ReadTheDocs (see #10496) #}
{% if page.canonical_url != 'https://docs.netbox.dev/' %}
{# Disable search indexing unless we're building for ReadTheDocs #}
{% if not config.extra.readthedocs %}
<meta name="robots" content="noindex">
{% endif %}
{% endblock %}

View File

@ -62,7 +62,7 @@ class MyModelImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
queryset=Site.objects.all(),
to_field_name='name',
help_text='Assigned site'
help_text=_('Assigned site')
)
class Meta:

View File

@ -1,20 +1,30 @@
# NetBox v3.7
## v3.7.6 (FUTURE)
## v3.7.7 (FUTURE)
---
## v3.7.6 (2024-04-22)
### Enhancements
* [#14690](https://github.com/netbox-community/netbox/issues/14690) - Improve rendering of JSON data in configuration form
* [#15427](https://github.com/netbox-community/netbox/issues/15427) - Enable compatibility with non-Amazon S3 providers for remote data sources
* [#15640](https://github.com/netbox-community/netbox/issues/15640) - Add global search support for L2VPN identifiers
* [#15644](https://github.com/netbox-community/netbox/issues/15644) - Introduce new configuration parameters for enabling HTTP Strict Transport Security (HSTS)
### Bug Fixes
* [#15541](https://github.com/netbox-community/netbox/issues/15541) - Restore ability to modify assigned component template when adding/modifying an inventory item template
* [#15582](https://github.com/netbox-community/netbox/issues/15582) - Fix permission constraints for synchronization of remote data sources
* [#15588](https://github.com/netbox-community/netbox/issues/15588) - Correct OpenAPI schema definitions for read-only fields which may return null values
* [#15635](https://github.com/netbox-community/netbox/issues/15635) - Extend plugin removal instruction to include reindexing the global search cache
* [#15654](https://github.com/netbox-community/netbox/issues/15654) - Fix `AttributeError` exception when attempting to save an incomplete tunnel termination
* [#15668](https://github.com/netbox-community/netbox/issues/15668) - Fix permission required to display virtual disks tab on virtual machine UI view
* [#15685](https://github.com/netbox-community/netbox/issues/15685) - Allow filtering cables by decimal values using UI filter form
* [#15761](https://github.com/netbox-community/netbox/issues/15761) - Add missing `ike_policy` & `ike_policy_id` filters for IKE proposals
* [#15771](https://github.com/netbox-community/netbox/issues/15771) - Include `id` in list of supported fields for all bulk import forms
* [#15790](https://github.com/netbox-community/netbox/issues/15790) - Fix live preview support for EventRule comments
---

View File

@ -42,6 +42,7 @@ plugins:
show_root_toc_entry: false
show_source: false
extra:
readthedocs: !ENV READTHEDOCS
social:
- icon: fontawesome/brands/github
link: https://github.com/netbox-community/netbox

View File

@ -3,6 +3,7 @@ import json
from django import forms
from django.conf import settings
from django.forms.fields import JSONField as _JSONField
from django.utils.translation import gettext_lazy as _
from core.forms.mixins import SyncedDataMixin
@ -12,7 +13,7 @@ from netbox.forms import NetBoxModelForm
from netbox.registry import registry
from netbox.utils import get_data_backend_choices
from utilities.forms import BootstrapMixin, get_field_value
from utilities.forms.fields import CommentField
from utilities.forms.fields import CommentField, JSONField
from utilities.forms.widgets import HTMXSelect
__all__ = (
@ -132,6 +133,9 @@ class ConfigFormMetaclass(forms.models.ModelFormMetaclass):
'help_text': param.description,
}
field_kwargs.update(**param.field_kwargs)
if param.field is _JSONField:
# Replace with our own JSONField to get pretty JSON in config editor
param.field = JSONField
param_fields[param.name] = param.field(**field_kwargs)
attrs.update(param_fields)

View File

@ -668,7 +668,7 @@ class DeviceSerializer(NetBoxModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name='dcim-api:device-detail')
device_type = NestedDeviceTypeSerializer()
role = NestedDeviceRoleSerializer()
device_role = NestedDeviceRoleSerializer(read_only=True, help_text='Deprecated in v3.6 in favor of `role`.')
device_role = NestedDeviceRoleSerializer(read_only=True, help_text=_('Deprecated in v3.6 in favor of `role`.'))
tenant = NestedTenantSerializer(required=False, allow_null=True, default=None)
platform = NestedPlatformSerializer(required=False, allow_null=True)
site = NestedSiteSerializer()

View File

@ -399,6 +399,10 @@ class PowerPortTypeChoices(ChoiceSet):
TYPE_USB_MICRO_AB = 'usb-micro-ab'
TYPE_USB_3_B = 'usb-3-b'
TYPE_USB_3_MICROB = 'usb-3-micro-b'
# Molex
TYPE_MOLEX_MICRO_FIT_1X2 = 'molex-micro-fit-1x2'
TYPE_MOLEX_MICRO_FIT_2X2 = 'molex-micro-fit-2x2'
TYPE_MOLEX_MICRO_FIT_2X4 = 'molex-micro-fit-2x4'
# Direct current (DC)
TYPE_DC = 'dc-terminal'
# Proprietary
@ -520,6 +524,11 @@ class PowerPortTypeChoices(ChoiceSet):
(TYPE_USB_3_B, 'USB 3.0 Type B'),
(TYPE_USB_3_MICROB, 'USB 3.0 Micro B'),
)),
('Molex', (
(TYPE_MOLEX_MICRO_FIT_1X2, 'Molex Micro-Fit 1x2'),
(TYPE_MOLEX_MICRO_FIT_2X2, 'Molex Micro-Fit 2x2'),
(TYPE_MOLEX_MICRO_FIT_2X4, 'Molex Micro-Fit 2x4'),
)),
('DC', (
(TYPE_DC, 'DC Terminal'),
)),
@ -635,6 +644,10 @@ class PowerOutletTypeChoices(ChoiceSet):
TYPE_USB_A = 'usb-a'
TYPE_USB_MICROB = 'usb-micro-b'
TYPE_USB_C = 'usb-c'
# Molex
TYPE_MOLEX_MICRO_FIT_1X2 = 'molex-micro-fit-1x2'
TYPE_MOLEX_MICRO_FIT_2X2 = 'molex-micro-fit-2x2'
TYPE_MOLEX_MICRO_FIT_2X4 = 'molex-micro-fit-2x4'
# Direct current (DC)
TYPE_DC = 'dc-terminal'
# Proprietary
@ -749,6 +762,11 @@ class PowerOutletTypeChoices(ChoiceSet):
(TYPE_USB_MICROB, 'USB Micro B'),
(TYPE_USB_C, 'USB Type C'),
)),
('Molex', (
(TYPE_MOLEX_MICRO_FIT_1X2, 'Molex Micro-Fit 1x2'),
(TYPE_MOLEX_MICRO_FIT_2X2, 'Molex Micro-Fit 2x2'),
(TYPE_MOLEX_MICRO_FIT_2X4, 'Molex Micro-Fit 2x4'),
)),
('DC', (
(TYPE_DC, 'DC Terminal'),
)),

View File

@ -1373,14 +1373,14 @@ class VirtualDeviceContextImportForm(NetBoxModelImportForm):
label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name',
help_text='Assigned role'
help_text=_('Assigned role')
)
tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text='Assigned tenant'
help_text=_('Assigned tenant')
)
status = CSVChoiceField(
label=_('Status'),

View File

@ -976,21 +976,67 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
queryset=Manufacturer.objects.all(),
required=False
)
component_type = ContentTypeChoiceField(
queryset=ContentType.objects.all(),
limit_choices_to=MODULAR_COMPONENT_TEMPLATE_MODELS,
# Assigned component selectors
consoleporttemplate = DynamicModelChoiceField(
queryset=ConsolePortTemplate.objects.all(),
required=False,
widget=forms.HiddenInput
query_params={
'device_type_id': '$device_type'
},
label=_('Console port template')
)
component_id = forms.IntegerField(
consoleserverporttemplate = DynamicModelChoiceField(
queryset=ConsoleServerPortTemplate.objects.all(),
required=False,
widget=forms.HiddenInput
query_params={
'device_type_id': '$device_type'
},
label=_('Console server port template')
)
frontporttemplate = DynamicModelChoiceField(
queryset=FrontPortTemplate.objects.all(),
required=False,
query_params={
'device_type_id': '$device_type'
},
label=_('Front port template')
)
interfacetemplate = DynamicModelChoiceField(
queryset=InterfaceTemplate.objects.all(),
required=False,
query_params={
'device_type_id': '$device_type'
},
label=_('Interface template')
)
poweroutlettemplate = DynamicModelChoiceField(
queryset=PowerOutletTemplate.objects.all(),
required=False,
query_params={
'device_type_id': '$device_type'
},
label=_('Power outlet template')
)
powerporttemplate = DynamicModelChoiceField(
queryset=PowerPortTemplate.objects.all(),
required=False,
query_params={
'device_type_id': '$device_type'
},
label=_('Power port template')
)
rearporttemplate = DynamicModelChoiceField(
queryset=RearPortTemplate.objects.all(),
required=False,
query_params={
'device_type_id': '$device_type'
},
label=_('Rear port template')
)
fieldsets = (
(None, (
'device_type', 'parent', 'name', 'label', 'role', 'manufacturer', 'part_id', 'description',
'component_type', 'component_id',
)),
)
@ -998,9 +1044,52 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
model = InventoryItemTemplate
fields = [
'device_type', 'parent', 'name', 'label', 'role', 'manufacturer', 'part_id', 'description',
'component_type', 'component_id',
]
def __init__(self, *args, **kwargs):
instance = kwargs.get('instance')
initial = kwargs.get('initial', {}).copy()
component_type = initial.get('component_type')
component_id = initial.get('component_id')
# Used for picking the default active tab for component selection
self.no_component = True
if instance:
# When editing set the initial value for component selection
for component_model in ContentType.objects.filter(MODULAR_COMPONENT_TEMPLATE_MODELS):
if type(instance.component) is component_model.model_class():
initial[component_model.model] = instance.component
self.no_component = False
break
elif component_type and component_id:
# When adding the InventoryItem from a component page
if content_type := ContentType.objects.filter(MODULAR_COMPONENT_TEMPLATE_MODELS).filter(pk=component_type).first():
if component := content_type.model_class().objects.filter(pk=component_id).first():
initial[content_type.model] = component
self.no_component = False
kwargs['initial'] = initial
super().__init__(*args, **kwargs)
def clean(self):
super().clean()
# Handle object assignment
selected_objects = [
field for field in (
'consoleporttemplate', 'consoleserverporttemplate', 'frontporttemplate', 'interfacetemplate',
'poweroutlettemplate', 'powerporttemplate', 'rearporttemplate'
) if self.cleaned_data[field]
]
if len(selected_objects) > 1:
raise forms.ValidationError(_("An InventoryItem can only be assigned to a single component."))
elif selected_objects:
self.instance.component = self.cleaned_data[selected_objects[0]]
else:
self.instance.component = None
#
# Device components

View File

@ -1656,6 +1656,7 @@ class InventoryItemTemplateCreateView(generic.ComponentCreateView):
queryset = InventoryItemTemplate.objects.all()
form = forms.InventoryItemTemplateCreateForm
model_form = forms.InventoryItemTemplateForm
template_name = 'dcim/inventoryitemtemplate_edit.html'
def alter_object(self, instance, request):
# Set component (if any)
@ -1673,6 +1674,7 @@ class InventoryItemTemplateCreateView(generic.ComponentCreateView):
class InventoryItemTemplateEditView(generic.ObjectEditView):
queryset = InventoryItemTemplate.objects.all()
form = forms.InventoryItemTemplateForm
template_name = 'dcim/inventoryitemtemplate_edit.html'
@register_model_view(InventoryItemTemplate, 'delete')

View File

@ -73,17 +73,12 @@ class NetBoxModelImportForm(CSVModelForm, NetBoxModelForm):
"""
Base form for creating a NetBox objects from CSV data. Used for bulk importing.
"""
id = forms.IntegerField(
label=_('Id'),
required=False,
help_text='Numeric ID of an existing object to update (if not creating a new object)'
)
tags = CSVModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(),
required=False,
to_field_name='slug',
help_text='Tag slugs separated by commas, encased with double quotes (e.g. "tag1,tag2,tag3")'
help_text=_('Tag slugs separated by commas, encased with double quotes (e.g. "tag1,tag2,tag3")')
)
def _get_custom_fields(self, content_type):

View File

@ -28,7 +28,7 @@ from netbox.plugins import PluginConfig
# Environment setup
#
VERSION = '3.7.6-dev'
VERSION = '3.7.7-dev'
# Hostname
HOSTNAME = platform.node()

View File

@ -0,0 +1,104 @@
{% extends 'generic/object_edit.html' %}
{% load static %}
{% load form_helpers %}
{% load helpers %}
{% load i18n %}
{% block form %}
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="offset-sm-3">{% trans "Inventory Item" %}</h5>
</div>
{% render_field form.device_type %}
{% render_field form.parent %}
{% render_field form.name %}
{% render_field form.label %}
{% render_field form.role %}
{% render_field form.description %}
</div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="offset-sm-3">{% trans "Hardware" %}</h5>
</div>
{% render_field form.manufacturer %}
{% render_field form.part_id %}
</div>
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="offset-sm-3">{% trans "Component Assignment" %}</h5>
</div>
<div class="row mb-2 offset-sm-3">
<ul class="nav nav-pills" role="tablist">
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="consoleport_tab" data-bs-toggle="tab" aria-controls="consoleport" data-bs-target="#consoleport" class="nav-link {% if form.initial.consoleporttemplate or form.no_component %}active{% endif %}">
{% trans "Console Port" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="consoleserverport_tab" data-bs-toggle="tab" aria-controls="consoleserverport" data-bs-target="#consoleserverport" class="nav-link {% if form.initial.consoleserverporttemplate %}active{% endif %}">
{% trans "Console Server Port" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="frontport_tab" data-bs-toggle="tab" aria-controls="frontport" data-bs-target="#frontport" class="nav-link {% if form.initial.frontporttemplate %}active{% endif %}">
{% trans "Front Port" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="interface_tab" data-bs-toggle="tab" aria-controls="interface" data-bs-target="#interface" class="nav-link {% if form.initial.interfacetemplate %}active{% endif %}">
{% trans "Interface" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="poweroutlet_tab" data-bs-toggle="tab" aria-controls="poweroutlet" data-bs-target="#poweroutlet" class="nav-link {% if form.initial.poweroutlettemplate %}active{% endif %}">
{% trans "Power Outlet" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="powerport_tab" data-bs-toggle="tab" aria-controls="powerport" data-bs-target="#powerport" class="nav-link {% if form.initial.powerporttemplate %}active{% endif %}">
{% trans "Power Port" %}
</button>
</li>
<li role="presentation" class="nav-item">
<button role="tab" type="button" id="rearport_tab" data-bs-toggle="tab" aria-controls="rearport" data-bs-target="#rearport" class="nav-link {% if form.initial.rearporttemplate %}active{% endif %}">
{% trans "Rear Port" %}
</button>
</li>
</ul>
</div>
<div class="tab-content p-0 border-0">
<div class="tab-pane {% if form.initial.consoleporttemplate or form.no_component %}active{% endif %}" id="consoleport" role="tabpanel" aria-labeled-by="consoleport_tab">
{% render_field form.consoleporttemplate %}
</div>
<div class="tab-pane {% if form.initial.consoleserverporttemplate %}active{% endif %}" id="consoleserverport" role="tabpanel" aria-labeled-by="consoleserverport_tab">
{% render_field form.consoleserverporttemplate %}
</div>
<div class="tab-pane {% if form.initial.frontporttemplate %}active{% endif %}" id="frontport" role="tabpanel" aria-labeled-by="frontport_tab">
{% render_field form.frontporttemplate %}
</div>
<div class="tab-pane {% if form.initial.interfacetemplate %}active{% endif %}" id="interface" role="tabpanel" aria-labeled-by="interface_tab">
{% render_field form.interfacetemplate %}
</div>
<div class="tab-pane {% if form.initial.poweroutlettemplate %}active{% endif %}" id="poweroutlet" role="tabpanel" aria-labeled-by="poweroutlet_tab">
{% render_field form.poweroutlettemplate %}
</div>
<div class="tab-pane {% if form.initial.powerporttemplate %}active{% endif %}" id="powerport" role="tabpanel" aria-labeled-by="powerport_tab">
{% render_field form.powerporttemplate %}
</div>
<div class="tab-pane {% if form.initial.rearporttemplate %}active{% endif %}" id="rearport" role="tabpanel" aria-labeled-by="rearport_tab">
{% render_field form.rearporttemplate %}
</div>
</div>
</div>
{% if form.custom_fields %}
<div class="field-group my-5">
<div class="row mb-2">
<h5 class="offset-sm-3">{% trans "Custom Fields" %}</h5>
</div>
{% render_custom_fields form %}
</div>
{% endif %}
{% endblock %}

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@
# Translators:
# Jonathan Senecal, 2024
# Jeremy Stretch, 2024
# Quentin Laurent, 2024
#
#, fuzzy
msgid ""
@ -14,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-04 19:11+0000\n"
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
"Last-Translator: Jeremy Stretch, 2024\n"
"Last-Translator: Quentin Laurent, 2024\n"
"Language-Team: French (https://app.transifex.com/netbox-community/teams/178115/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -3716,7 +3717,7 @@ msgstr "Réservation"
#: dcim/forms/model_forms.py:301 dcim/forms/model_forms.py:384
#: utilities/forms/fields/fields.py:47
msgid "Slug"
msgstr "limace"
msgstr "Identifiant"
#: dcim/forms/model_forms.py:308 templates/dcim/devicetype.html:12
msgid "Chassis"
@ -5813,7 +5814,7 @@ msgstr "Poids maximum"
#: ipam/tables/asn.py:66 netbox/navigation/menu.py:16
#: netbox/navigation/menu.py:18
msgid "Sites"
msgstr "Des sites"
msgstr "Sites"
#: dcim/tests/test_api.py:49
msgid "Test case must set peer_termination_type"
@ -13355,7 +13356,7 @@ msgstr ""
#: utilities/forms/fields/fields.py:48
msgid "URL-friendly unique shorthand"
msgstr "Raccourci unique et convivial pour les URL"
msgstr "Identifiant unique utilisable dans les URL"
#: utilities/forms/fields/fields.py:101
msgid "Enter context data in <a href=\"https://json.org/\">JSON</a> format."

View File

@ -5,8 +5,8 @@
#
# Translators:
# Tatsuya Ueda <ml@tatsuya.info>, 2024
# teapot, 2024
# Jeremy Stretch, 2024
# teapot, 2024
#
#, fuzzy
msgid ""
@ -15,7 +15,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-04 19:11+0000\n"
"PO-Revision-Date: 2023-10-30 17:48+0000\n"
"Last-Translator: Jeremy Stretch, 2024\n"
"Last-Translator: teapot, 2024\n"
"Language-Team: Japanese (https://app.transifex.com/netbox-community/teams/178115/ja/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -7681,7 +7681,7 @@ msgstr "プレフィックス内およびプレフィックスを含む"
#: ipam/filtersets.py:259
msgid "Prefixes which contain this prefix or IP"
msgstr "このプレフィックスまたは IP を含むプレフィックス"
msgstr "このプレフィックス / IP を含むプレフィックス"
#: ipam/filtersets.py:270 ipam/filtersets.py:538 ipam/forms/bulk_edit.py:326
#: ipam/forms/filtersets.py:191 ipam/forms/filtersets.py:317
@ -7700,11 +7700,11 @@ msgstr "VLAN 番号 (1-4094)"
#: ipam/forms/model_forms.py:430 templates/tenancy/contact.html:54
#: tenancy/forms/bulk_edit.py:112
msgid "Address"
msgstr "住所"
msgstr "アドレス"
#: ipam/filtersets.py:445
msgid "Ranges which contain this prefix or IP"
msgstr "このプレフィックスまたは IP を含む範囲"
msgstr "このプレフィックス / IP を含む範囲"
#: ipam/filtersets.py:473 ipam/filtersets.py:529
msgid "Parent prefix"
@ -7743,11 +7743,11 @@ msgstr "FHRP グループ (ID)"
#: ipam/filtersets.py:618
msgid "Is assigned to an interface"
msgstr "インタフェースに割り当てられている"
msgstr "インタフェースに割り当てられている"
#: ipam/filtersets.py:622
msgid "Is assigned"
msgstr "割り当てられている"
msgstr "割当済みか"
#: ipam/filtersets.py:1047
msgid "IP address (ID)"
@ -7881,7 +7881,7 @@ msgstr "子 VLAN VID の最小値"
#: ipam/forms/bulk_edit.py:420
msgid "Maximum child VLAN VID"
msgstr "子 VLAN VID の最大"
msgstr "子 VLAN VID の最大"
#: ipam/forms/bulk_edit.py:428 ipam/forms/model_forms.py:531
msgid "Scope type"
@ -7905,11 +7905,11 @@ msgstr "ポート"
#: ipam/forms/bulk_import.py:47
msgid "Import route targets"
msgstr "ルートターゲットをインポート"
msgstr "インポートルートターゲット"
#: ipam/forms/bulk_import.py:53
msgid "Export route targets"
msgstr "ルートターゲットをエクスポートする"
msgstr "エクスポートルートターゲット"
#: ipam/forms/bulk_import.py:91 ipam/forms/bulk_import.py:111
#: ipam/forms/bulk_import.py:131

View File

@ -70,6 +70,12 @@ class CSVModelForm(forms.ModelForm):
"""
ModelForm used for the import of objects in CSV format.
"""
id = forms.IntegerField(
label=_('ID'),
required=False,
help_text=_('Numeric ID of an existing object to update (if not creating a new object)')
)
def __init__(self, *args, headers=None, **kwargs):
self.headers = headers or {}
super().__init__(*args, **kwargs)

View File

@ -42,7 +42,7 @@ class WirelessLANImportForm(NetBoxModelImportForm):
status = CSVChoiceField(
label=_('Status'),
choices=WirelessLANStatusChoices,
help_text='Operational status'
help_text=_('Operational status')
)
vlan = CSVModelChoiceField(
label=_('VLAN'),

View File

@ -18,11 +18,11 @@ drf-spectacular==0.27.2
drf-spectacular-sidecar==2024.4.1
feedparser==6.0.11
graphene-django==3.0.0
gunicorn==21.2.0
gunicorn==22.0.0
Jinja2==3.1.3
Markdown==3.6
mkdocs-material==9.5.17
mkdocstrings[python-legacy]==0.24.2
mkdocs-material==9.5.18
mkdocstrings[python-legacy]==0.24.3
netaddr==1.2.1
Pillow==10.3.0
psycopg[binary,pool]==3.1.18