diff --git a/netbox/circuits/forms/bulk_edit.py b/netbox/circuits/forms/bulk_edit.py
index 9dba87e47..1a9366583 100644
--- a/netbox/circuits/forms/bulk_edit.py
+++ b/netbox/circuits/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from circuits.choices import CircuitCommitRateChoices, CircuitStatusChoices
from circuits.models import *
@@ -26,12 +26,11 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = Provider
fieldsets = (
@@ -44,16 +43,16 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm):
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = ProviderAccount
fieldsets = (
@@ -66,6 +65,7 @@ class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm):
class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
required=False
)
@@ -75,12 +75,11 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
label=_('Service ID')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = ProviderNetwork
fieldsets = (
@@ -93,6 +92,7 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -106,14 +106,17 @@ class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
class CircuitBulkEditForm(NetBoxModelBulkEditForm):
type = DynamicModelChoiceField(
+ label=_('Type'),
queryset=CircuitType.objects.all(),
required=False
)
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
required=False
)
provider_account = DynamicModelChoiceField(
+ label=_('Provider account'),
queryset=ProviderAccount.objects.all(),
required=False,
query_params={
@@ -121,19 +124,23 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
}
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(CircuitStatusChoices),
required=False,
initial=''
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
install_date = forms.DateField(
+ label=_('Install date'),
required=False,
widget=DatePicker()
)
termination_date = forms.DateField(
+ label=_('Termination date'),
required=False,
widget=DatePicker()
)
@@ -145,18 +152,17 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
)
)
description = forms.CharField(
+ label=_('Description'),
max_length=100,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = Circuit
fieldsets = (
- ('Circuit', ('provider', 'type', 'status', 'description')),
- ('Service Parameters', ('provider_account', 'install_date', 'termination_date', 'commit_rate')),
- ('Tenancy', ('tenant',)),
+ (_('Circuit'), ('provider', 'type', 'status', 'description')),
+ (_('Service Parameters'), ('provider_account', 'install_date', 'termination_date', 'commit_rate')),
+ (_('Tenancy'), ('tenant',)),
)
nullable_fields = (
'tenant', 'commit_rate', 'description', 'comments',
diff --git a/netbox/circuits/forms/bulk_import.py b/netbox/circuits/forms/bulk_import.py
index 3941ef574..d2217b45b 100644
--- a/netbox/circuits/forms/bulk_import.py
+++ b/netbox/circuits/forms/bulk_import.py
@@ -3,7 +3,7 @@ from django import forms
from circuits.choices import CircuitStatusChoices
from circuits.models import *
from dcim.models import Site
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelImportForm
from tenancy.models import Tenant
from utilities.forms import BootstrapMixin
@@ -31,6 +31,7 @@ class ProviderImportForm(NetBoxModelImportForm):
class ProviderAccountImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
to_field_name='name',
help_text=_('Assigned provider')
@@ -45,6 +46,7 @@ class ProviderAccountImportForm(NetBoxModelImportForm):
class ProviderNetworkImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
to_field_name='name',
help_text=_('Assigned provider')
@@ -67,26 +69,31 @@ class CircuitTypeImportForm(NetBoxModelImportForm):
class CircuitImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
to_field_name='name',
help_text=_('Assigned provider')
)
provider_account = CSVModelChoiceField(
+ label=_('Provider account'),
queryset=ProviderAccount.objects.all(),
to_field_name='name',
help_text=_('Assigned provider account'),
required=False
)
type = CSVModelChoiceField(
+ label=_('Type'),
queryset=CircuitType.objects.all(),
to_field_name='name',
help_text=_('Type of circuit')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=CircuitStatusChoices,
help_text=_('Operational status')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -103,11 +110,13 @@ class CircuitImportForm(NetBoxModelImportForm):
class CircuitTerminationImportForm(BootstrapMixin, forms.ModelForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
required=False
)
provider_network = CSVModelChoiceField(
+ label=_('Provider network'),
queryset=ProviderNetwork.objects.all(),
to_field_name='name',
required=False
diff --git a/netbox/circuits/forms/filtersets.py b/netbox/circuits/forms/filtersets.py
index 83da0d50a..1fb239023 100644
--- a/netbox/circuits/forms/filtersets.py
+++ b/netbox/circuits/forms/filtersets.py
@@ -23,9 +23,9 @@ class ProviderFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Provider
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('ASN', ('asn',)),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('ASN'), ('asn',)),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -62,7 +62,7 @@ class ProviderAccountFilterForm(NetBoxModelFilterSetForm):
model = ProviderAccount
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('provider_id', 'account')),
+ (_('Attributes'), ('provider_id', 'account')),
)
provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(),
@@ -70,6 +70,7 @@ class ProviderAccountFilterForm(NetBoxModelFilterSetForm):
label=_('Provider')
)
account = forms.CharField(
+ label=_('Account'),
required=False
)
tag = TagFilterField(model)
@@ -79,7 +80,7 @@ class ProviderNetworkFilterForm(NetBoxModelFilterSetForm):
model = ProviderNetwork
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('provider_id', 'service_id')),
+ (_('Attributes'), ('provider_id', 'service_id')),
)
provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(),
@@ -87,6 +88,7 @@ class ProviderNetworkFilterForm(NetBoxModelFilterSetForm):
label=_('Provider')
)
service_id = forms.CharField(
+ label=_('Service id'),
max_length=100,
required=False
)
@@ -102,11 +104,11 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
model = Circuit
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Provider', ('provider_id', 'provider_account_id', 'provider_network_id')),
- ('Attributes', ('type_id', 'status', 'install_date', 'termination_date', 'commit_rate')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Provider'), ('provider_id', 'provider_account_id', 'provider_network_id')),
+ (_('Attributes'), ('type_id', 'status', 'install_date', 'termination_date', 'commit_rate')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
type_id = DynamicModelMultipleChoiceField(
queryset=CircuitType.objects.all(),
@@ -135,6 +137,7 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Provider network')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=CircuitStatusChoices,
required=False
)
@@ -158,10 +161,12 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Site')
)
install_date = forms.DateField(
+ label=_('Install date'),
required=False,
widget=DatePicker
)
termination_date = forms.DateField(
+ label=_('Termination date'),
required=False,
widget=DatePicker
)
diff --git a/netbox/circuits/forms/model_forms.py b/netbox/circuits/forms/model_forms.py
index d3929c08a..8a540032e 100644
--- a/netbox/circuits/forms/model_forms.py
+++ b/netbox/circuits/forms/model_forms.py
@@ -1,4 +1,4 @@
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from circuits.choices import CircuitCommitRateChoices, CircuitTerminationPortSpeedChoices
from circuits.models import *
@@ -29,7 +29,7 @@ class ProviderForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Provider', ('name', 'slug', 'asns', 'description', 'tags')),
+ (_('Provider'), ('name', 'slug', 'asns', 'description', 'tags')),
)
class Meta:
@@ -41,6 +41,7 @@ class ProviderForm(NetBoxModelForm):
class ProviderAccountForm(NetBoxModelForm):
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all()
)
comments = CommentField()
@@ -54,12 +55,13 @@ class ProviderAccountForm(NetBoxModelForm):
class ProviderNetworkForm(NetBoxModelForm):
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all()
)
comments = CommentField()
fieldsets = (
- ('Provider Network', ('provider', 'name', 'service_id', 'description', 'tags')),
+ (_('Provider Network'), ('provider', 'name', 'service_id', 'description', 'tags')),
)
class Meta:
@@ -73,7 +75,7 @@ class CircuitTypeForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Circuit Type', (
+ (_('Circuit Type'), (
'name', 'slug', 'description', 'tags',
)),
)
@@ -87,10 +89,12 @@ class CircuitTypeForm(NetBoxModelForm):
class CircuitForm(TenancyForm, NetBoxModelForm):
provider = DynamicModelChoiceField(
+ label=_('Provider'),
queryset=Provider.objects.all(),
selector=True
)
provider_account = DynamicModelChoiceField(
+ label=_('Provider account'),
queryset=ProviderAccount.objects.all(),
required=False,
query_params={
@@ -103,9 +107,9 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Circuit', ('provider', 'provider_account', 'cid', 'type', 'status', 'description', 'tags')),
- ('Service Parameters', ('install_date', 'termination_date', 'commit_rate')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Circuit'), ('provider', 'provider_account', 'cid', 'type', 'status', 'description', 'tags')),
+ (_('Service Parameters'), ('install_date', 'termination_date', 'commit_rate')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -125,15 +129,18 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
class CircuitTerminationForm(NetBoxModelForm):
circuit = DynamicModelChoiceField(
+ label=_('Circuit'),
queryset=Circuit.objects.all(),
selector=True
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
selector=True
)
provider_network = DynamicModelChoiceField(
+ label=_('Provider network'),
queryset=ProviderNetwork.objects.all(),
required=False,
selector=True
diff --git a/netbox/core/forms/bulk_edit.py b/netbox/core/forms/bulk_edit.py
index de8727643..a4ecd646f 100644
--- a/netbox/core/forms/bulk_edit.py
+++ b/netbox/core/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from core.choices import DataSourceTypeChoices
from core.models import *
@@ -15,6 +15,7 @@ __all__ = (
class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(DataSourceTypeChoices),
required=False,
initial=''
@@ -25,16 +26,17 @@ class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
label=_('Enforce unique space')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
parameters = forms.JSONField(
+ label=_('Parameters'),
required=False
)
ignore_rules = forms.CharField(
+ label=_('Ignore rules'),
required=False,
widget=forms.Textarea()
)
diff --git a/netbox/core/forms/filtersets.py b/netbox/core/forms/filtersets.py
index d8624f6b6..f7a6f3595 100644
--- a/netbox/core/forms/filtersets.py
+++ b/netbox/core/forms/filtersets.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from core.choices import *
from core.models import *
@@ -23,17 +23,20 @@ class DataSourceFilterForm(NetBoxModelFilterSetForm):
model = DataSource
fieldsets = (
(None, ('q', 'filter_id')),
- ('Data Source', ('type', 'status')),
+ (_('Data Source'), ('type', 'status')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=DataSourceTypeChoices,
required=False
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=DataSourceStatusChoices,
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -45,7 +48,7 @@ class DataFileFilterForm(NetBoxModelFilterSetForm):
model = DataFile
fieldsets = (
(None, ('q', 'filter_id')),
- ('File', ('source_id',)),
+ (_('File'), ('source_id',)),
)
source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(),
@@ -57,8 +60,8 @@ class DataFileFilterForm(NetBoxModelFilterSetForm):
class JobFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Attributes', ('object_type', 'status')),
- ('Creation', (
+ (_('Attributes'), ('object_type', 'status')),
+ (_('Creation'), (
'created__before', 'created__after', 'scheduled__before', 'scheduled__after', 'started__before',
'started__after', 'completed__before', 'completed__after', 'user',
)),
@@ -69,38 +72,47 @@ class JobFilterForm(SavedFiltersMixin, FilterForm):
required=False,
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=JobStatusChoices,
required=False
)
created__after = forms.DateTimeField(
+ label=_('Created after'),
required=False,
widget=DateTimePicker()
)
created__before = forms.DateTimeField(
+ label=_('Created before'),
required=False,
widget=DateTimePicker()
)
scheduled__after = forms.DateTimeField(
+ label=_('Scheduled after'),
required=False,
widget=DateTimePicker()
)
scheduled__before = forms.DateTimeField(
+ label=_('Scheduled before'),
required=False,
widget=DateTimePicker()
)
started__after = forms.DateTimeField(
+ label=_('Started after'),
required=False,
widget=DateTimePicker()
)
started__before = forms.DateTimeField(
+ label=_('Started before'),
required=False,
widget=DateTimePicker()
)
completed__after = forms.DateTimeField(
+ label=_('Completed after'),
required=False,
widget=DateTimePicker()
)
completed__before = forms.DateTimeField(
+ label=_('Completed before'),
required=False,
widget=DateTimePicker()
)
diff --git a/netbox/core/forms/mixins.py b/netbox/core/forms/mixins.py
index 3e76f67a2..0b559fa57 100644
--- a/netbox/core/forms/mixins.py
+++ b/netbox/core/forms/mixins.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from core.models import DataFile, DataSource
from utilities.forms.fields import DynamicModelChoiceField
diff --git a/netbox/core/forms/model_forms.py b/netbox/core/forms/model_forms.py
index 666a19e85..01d5474c6 100644
--- a/netbox/core/forms/model_forms.py
+++ b/netbox/core/forms/model_forms.py
@@ -1,6 +1,7 @@
import copy
from django import forms
+from django.utils.translation import gettext_lazy as _
from core.forms.mixins import SyncedDataMixin
from core.models import *
@@ -38,11 +39,11 @@ class DataSourceForm(NetBoxModelForm):
@property
def fieldsets(self):
fieldsets = [
- ('Source', ('name', 'type', 'source_url', 'enabled', 'description', 'tags', 'ignore_rules')),
+ (_('Source'), ('name', 'type', 'source_url', 'enabled', 'description', 'tags', 'ignore_rules')),
]
if self.backend_fields:
fieldsets.append(
- ('Backend Parameters', self.backend_fields)
+ (_('Backend Parameters'), self.backend_fields)
)
return fieldsets
@@ -79,8 +80,8 @@ class ManagedFileForm(SyncedDataMixin, NetBoxModelForm):
)
fieldsets = (
- ('File Upload', ('upload_file',)),
- ('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')),
+ (_('File Upload'), ('upload_file',)),
+ (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
)
class Meta:
diff --git a/netbox/dcim/forms/bulk_create.py b/netbox/dcim/forms/bulk_create.py
index 2d86a1718..02aa5a3e4 100644
--- a/netbox/dcim/forms/bulk_create.py
+++ b/netbox/dcim/forms/bulk_create.py
@@ -1,7 +1,7 @@
from django import forms
from dcim.models import *
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.forms import CustomFieldsMixin
from extras.models import Tag
from utilities.forms import BootstrapMixin, form_from_model
@@ -32,10 +32,12 @@ class DeviceBulkAddComponentForm(BootstrapMixin, CustomFieldsMixin, ComponentCre
widget=forms.MultipleHiddenInput()
)
description = forms.CharField(
+ label=_('Description'),
max_length=100,
required=False
)
tags = DynamicModelMultipleChoiceField(
+ label=_('Tags'),
queryset=Tag.objects.all(),
required=False
)
diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py
index 9ee938859..33e60322d 100644
--- a/netbox/dcim/forms/bulk_edit.py
+++ b/netbox/dcim/forms/bulk_edit.py
@@ -1,7 +1,7 @@
from django import forms
from django.conf import settings
from django.contrib.auth import get_user_model
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from timezone_field import TimeZoneFormField
from dcim.choices import *
@@ -63,10 +63,12 @@ __all__ = (
class RegionBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=Region.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -80,10 +82,12 @@ class RegionBulkEditForm(NetBoxModelBulkEditForm):
class SiteGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=SiteGroup.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -97,19 +101,23 @@ class SiteGroupBulkEditForm(NetBoxModelBulkEditForm):
class SiteBulkEditForm(NetBoxModelBulkEditForm):
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(SiteStatusChoices),
required=False,
initial=''
)
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=SiteGroup.objects.all(),
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
@@ -119,10 +127,12 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
contact_name = forms.CharField(
+ label=_('Contact name'),
max_length=50,
required=False
)
contact_phone = forms.CharField(
+ label=_('Contact phone'),
max_length=20,
required=False
)
@@ -131,16 +141,16 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
label=_('Contact E-mail')
)
time_zone = TimeZoneFormField(
+ label=_('Time zone'),
choices=add_blank_choice(TimeZoneFormField().choices),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Site
fieldsets = (
@@ -153,10 +163,12 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
class LocationBulkEditForm(NetBoxModelBulkEditForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False
)
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -164,15 +176,18 @@ class LocationBulkEditForm(NetBoxModelBulkEditForm):
}
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(LocationStatusChoices),
required=False,
initial=''
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -186,9 +201,11 @@ class LocationBulkEditForm(NetBoxModelBulkEditForm):
class RackRoleBulkEditForm(NetBoxModelBulkEditForm):
color = ColorField(
+ label=_('Color'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -202,6 +219,7 @@ class RackRoleBulkEditForm(NetBoxModelBulkEditForm):
class RackBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
initial_params={
@@ -209,6 +227,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
}
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False,
initial_params={
@@ -216,6 +235,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
}
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -224,6 +244,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
}
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -231,15 +252,18 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
}
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(RackStatusChoices),
required=False,
initial=''
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=RackRole.objects.all(),
required=False
)
@@ -249,14 +273,17 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
label=_('Serial Number')
)
asset_tag = forms.CharField(
+ label=_('Asset tag'),
max_length=50,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(RackTypeChoices),
required=False
)
width = forms.ChoiceField(
+ label=_('Width'),
choices=add_blank_choice(RackWidthChoices),
required=False
)
@@ -270,50 +297,56 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
label=_('Descending units')
)
outer_width = forms.IntegerField(
+ label=_('Outer width'),
required=False,
min_value=1
)
outer_depth = forms.IntegerField(
+ label=_('Outer depth'),
required=False,
min_value=1
)
outer_unit = forms.ChoiceField(
+ label=_('Outer unit'),
choices=add_blank_choice(RackDimensionUnitChoices),
required=False
)
mounting_depth = forms.IntegerField(
+ label=_('Mounting depth'),
required=False,
min_value=1
)
weight = forms.DecimalField(
+ label=_('Weight'),
min_value=0,
required=False
)
max_weight = forms.IntegerField(
+ label=_('Max weight'),
min_value=0,
required=False
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False,
initial=''
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Rack
fieldsets = (
- ('Rack', ('status', 'role', 'tenant', 'serial', 'asset_tag', 'description')),
- ('Location', ('region', 'site_group', 'site', 'location')),
- ('Hardware', (
+ (_('Rack'), ('status', 'role', 'tenant', 'serial', 'asset_tag', 'description')),
+ (_('Location'), ('region', 'site_group', 'site', 'location')),
+ (_('Hardware'), (
'type', 'width', 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
)),
- ('Weight', ('weight', 'max_weight', 'weight_unit')),
+ (_('Weight'), ('weight', 'max_weight', 'weight_unit')),
)
nullable_fields = (
'location', 'tenant', 'role', 'serial', 'asset_tag', 'outer_width', 'outer_depth', 'outer_unit', 'weight',
@@ -323,22 +356,23 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
user = forms.ModelChoiceField(
+ label=_('User'),
queryset=get_user_model().objects.order_by(
'username'
),
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = RackReservation
fieldsets = (
@@ -349,6 +383,7 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -362,17 +397,21 @@ class ManufacturerBulkEditForm(NetBoxModelBulkEditForm):
class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
default_platform = DynamicModelChoiceField(
+ label=_('Default platform'),
queryset=Platform.objects.all(),
required=False
)
part_number = forms.CharField(
+ label=_('Part number'),
required=False
)
u_height = forms.IntegerField(
+ label=_('U height'),
min_value=1,
required=False
)
@@ -382,69 +421,75 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
label=_('Is full depth')
)
airflow = forms.ChoiceField(
+ label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices),
required=False
)
weight = forms.DecimalField(
+ label=_('Weight'),
min_value=0,
required=False
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False,
initial=''
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = DeviceType
fieldsets = (
- ('Device Type', ('manufacturer', 'default_platform', 'part_number', 'u_height', 'is_full_depth', 'airflow', 'description')),
- ('Weight', ('weight', 'weight_unit')),
+ (_('Device Type'), ('manufacturer', 'default_platform', 'part_number', 'u_height', 'is_full_depth', 'airflow', 'description')),
+ (_('Weight'), ('weight', 'weight_unit')),
)
nullable_fields = ('part_number', 'airflow', 'weight', 'weight_unit', 'description', 'comments')
class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
part_number = forms.CharField(
+ label=_('Part number'),
required=False
)
weight = forms.DecimalField(
+ label=_('Weight'),
min_value=0,
required=False
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False,
initial=''
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = ModuleType
fieldsets = (
- ('Module Type', ('manufacturer', 'part_number', 'description')),
- ('Weight', ('weight', 'weight_unit')),
+ (_('Module Type'), ('manufacturer', 'part_number', 'description')),
+ (_('Weight'), ('weight', 'weight_unit')),
)
nullable_fields = ('part_number', 'weight', 'weight_unit', 'description', 'comments')
class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
color = ColorField(
+ label=_('Color'),
required=False
)
vm_role = forms.NullBooleanField(
@@ -453,10 +498,12 @@ class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
label=_('VM role')
)
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -470,14 +517,17 @@ class DeviceRoleBulkEditForm(NetBoxModelBulkEditForm):
class PlatformBulkEditForm(NetBoxModelBulkEditForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -491,10 +541,12 @@ class PlatformBulkEditForm(NetBoxModelBulkEditForm):
class DeviceBulkEditForm(NetBoxModelBulkEditForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
device_type = DynamicModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all(),
required=False,
query_params={
@@ -502,14 +554,17 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
}
)
device_role = DynamicModelChoiceField(
+ label=_('Device role'),
queryset=DeviceRole.objects.all(),
required=False
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -517,18 +572,22 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
}
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
platform = DynamicModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(DeviceStatusChoices),
required=False
)
airflow = forms.ChoiceField(
+ label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices),
required=False
)
@@ -538,23 +597,23 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
label=_('Serial Number')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Device
fieldsets = (
- ('Device', ('device_role', 'status', 'tenant', 'platform', 'description')),
- ('Location', ('site', 'location')),
- ('Hardware', ('manufacturer', 'device_type', 'airflow', 'serial')),
- ('Configuration', ('config_template',)),
+ (_('Device'), ('device_role', 'status', 'tenant', 'platform', 'description')),
+ (_('Location'), ('site', 'location')),
+ (_('Hardware'), ('manufacturer', 'device_type', 'airflow', 'serial')),
+ (_('Configuration'), ('config_template',)),
)
nullable_fields = (
'location', 'tenant', 'platform', 'serial', 'airflow', 'description', 'comments',
@@ -563,10 +622,12 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
class ModuleBulkEditForm(NetBoxModelBulkEditForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
module_type = DynamicModelChoiceField(
+ label=_('Module type'),
queryset=ModuleType.objects.all(),
required=False,
query_params={
@@ -574,6 +635,7 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
}
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(ModuleStatusChoices),
required=False,
initial=''
@@ -584,12 +646,11 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
label=_('Serial Number')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Module
fieldsets = (
@@ -600,47 +661,53 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
class CableBulkEditForm(NetBoxModelBulkEditForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(CableTypeChoices),
required=False,
initial=''
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(LinkStatusChoices),
required=False,
initial=''
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
label = forms.CharField(
+ label=_('Label'),
max_length=100,
required=False
)
color = ColorField(
+ label=_('Color'),
required=False
)
length = forms.DecimalField(
+ label=_('Length'),
min_value=0,
required=False
)
length_unit = forms.ChoiceField(
+ label=_('Length unit'),
choices=add_blank_choice(CableLengthUnitChoices),
required=False,
initial=''
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Cable
fieldsets = (
(None, ('type', 'status', 'tenant', 'label', 'description')),
- ('Attributes', ('color', 'length', 'length_unit')),
+ (_('Attributes'), ('color', 'length', 'length_unit')),
)
nullable_fields = (
'type', 'status', 'tenant', 'label', 'color', 'length', 'description', 'comments',
@@ -649,16 +716,16 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
domain = forms.CharField(
+ label=_('Domain'),
max_length=30,
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = VirtualChassis
fieldsets = (
@@ -669,6 +736,7 @@ class VirtualChassisBulkEditForm(NetBoxModelBulkEditForm):
class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
initial_params={
@@ -676,6 +744,7 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
}
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False,
initial_params={
@@ -683,6 +752,7 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
}
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -691,6 +761,7 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
}
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -698,12 +769,11 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
}
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = PowerPanel
fieldsets = (
@@ -714,43 +784,53 @@ class PowerPanelBulkEditForm(NetBoxModelBulkEditForm):
class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
power_panel = DynamicModelChoiceField(
+ label=_('Power panel'),
queryset=PowerPanel.objects.all(),
required=False
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(PowerFeedStatusChoices),
required=False,
initial=''
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PowerFeedTypeChoices),
required=False,
initial=''
)
supply = forms.ChoiceField(
+ label=_('Supply'),
choices=add_blank_choice(PowerFeedSupplyChoices),
required=False,
initial=''
)
phase = forms.ChoiceField(
+ label=_('Phase'),
choices=add_blank_choice(PowerFeedPhaseChoices),
required=False,
initial=''
)
voltage = forms.IntegerField(
+ label=_('Voltage'),
required=False
)
amperage = forms.IntegerField(
+ label=_('Amperage'),
required=False
)
max_utilization = forms.IntegerField(
+ label=_('Max utilization'),
required=False
)
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -759,17 +839,16 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = PowerFeed
fieldsets = (
(None, ('power_panel', 'rack', 'status', 'type', 'mark_connected', 'description', 'tenant')),
- ('Power', ('supply', 'phase', 'voltage', 'amperage', 'max_utilization'))
+ (_('Power'), ('supply', 'phase', 'voltage', 'amperage', 'max_utilization'))
)
nullable_fields = ('location', 'tenant', 'description', 'comments')
@@ -784,10 +863,12 @@ class ConsolePortTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(ConsolePortTypeChoices),
required=False
)
@@ -801,14 +882,17 @@ class ConsoleServerPortTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(ConsolePortTypeChoices),
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -821,24 +905,29 @@ class PowerPortTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PowerPortTypeChoices),
required=False
)
maximum_draw = forms.IntegerField(
+ label=_('Maximum draw'),
min_value=1,
required=False,
help_text=_("Maximum power draw (watts)")
)
allocated_draw = forms.IntegerField(
+ label=_('Allocated draw'),
min_value=1,
required=False,
help_text=_("Allocated power draw (watts)")
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -851,28 +940,34 @@ class PowerOutletTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
device_type = forms.ModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all(),
required=False,
disabled=True,
widget=forms.HiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PowerOutletTypeChoices),
required=False
)
power_port = forms.ModelChoiceField(
+ label=_('Power port'),
queryset=PowerPortTemplate.objects.all(),
required=False
)
feed_leg = forms.ChoiceField(
+ label=_('Feed leg'),
choices=add_blank_choice(PowerOutletFeedLegChoices),
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -896,14 +991,17 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(InterfaceTypeChoices),
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -913,6 +1011,7 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
label=_('Management only')
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
poe_mode = forms.ChoiceField(
@@ -943,17 +1042,21 @@ class FrontPortTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PortTypeChoices),
required=False
)
color = ColorField(
+ label=_('Color'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -966,17 +1069,21 @@ class RearPortTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PortTypeChoices),
required=False
)
color = ColorField(
+ label=_('Color'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -989,10 +1096,12 @@ class ModuleBayTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -1005,10 +1114,12 @@ class DeviceBayTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
@@ -1021,17 +1132,21 @@ class InventoryItemTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput()
)
label = forms.CharField(
+ label=_('Label'),
max_length=64,
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
required=False
)
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
@@ -1045,12 +1160,14 @@ class InventoryItemTemplateBulkEditForm(BulkEditForm):
class ComponentBulkEditForm(NetBoxModelBulkEditForm):
device = forms.ModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
disabled=True,
widget=forms.HiddenInput()
)
module = forms.ModelChoiceField(
+ label=_('Module'),
queryset=Module.objects.all(),
required=False
)
@@ -1072,6 +1189,7 @@ class ConsolePortBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1088,6 +1206,7 @@ class ConsoleServerPortBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1104,6 +1223,7 @@ class PowerPortBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1111,7 +1231,7 @@ class PowerPortBulkEditForm(
model = PowerPort
fieldsets = (
(None, ('module', 'type', 'label', 'description', 'mark_connected')),
- ('Power', ('maximum_draw', 'allocated_draw')),
+ (_('Power'), ('maximum_draw', 'allocated_draw')),
)
nullable_fields = ('module', 'label', 'description', 'maximum_draw', 'allocated_draw')
@@ -1121,6 +1241,7 @@ class PowerOutletBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1128,7 +1249,7 @@ class PowerOutletBulkEditForm(
model = PowerOutlet
fieldsets = (
(None, ('module', 'type', 'label', 'description', 'mark_connected')),
- ('Power', ('feed_leg', 'power_port')),
+ (_('Power'), ('feed_leg', 'power_port')),
)
nullable_fields = ('module', 'label', 'type', 'feed_leg', 'power_port', 'description')
@@ -1153,14 +1274,17 @@ class InterfaceBulkEditForm(
ComponentBulkEditForm
):
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect
)
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=Interface.objects.all(),
required=False
)
bridge = DynamicModelChoiceField(
+ label=_('Bridge'),
queryset=Interface.objects.all(),
required=False
)
@@ -1175,12 +1299,13 @@ class InterfaceBulkEditForm(
vdcs = DynamicModelMultipleChoiceField(
queryset=VirtualDeviceContext.objects.all(),
required=False,
- label='Virtual Device Contexts',
+ label=_('Virtual device contexts'),
query_params={
'device_id': '$device',
}
)
speed = forms.IntegerField(
+ label=_('Speed'),
required=False,
widget=NumberWithOptions(
options=InterfaceSpeedChoices
@@ -1204,10 +1329,12 @@ class InterfaceBulkEditForm(
label=_('PoE type')
)
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
mode = forms.ChoiceField(
+ label=_('Mode'),
choices=add_blank_choice(InterfaceModeChoices),
required=False,
initial=''
@@ -1255,12 +1382,12 @@ class InterfaceBulkEditForm(
model = Interface
fieldsets = (
(None, ('module', 'type', 'label', 'speed', 'duplex', 'description')),
- ('Addressing', ('vrf', 'mac_address', 'wwn')),
- ('Operation', ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
- ('PoE', ('poe_mode', 'poe_type')),
- ('Related Interfaces', ('parent', 'bridge', 'lag')),
- ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
- ('Wireless', (
+ (_('Addressing'), ('vrf', 'mac_address', 'wwn')),
+ (_('Operation'), ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
+ (_('PoE'), ('poe_mode', 'poe_type')),
+ (_('Related Interfaces'), ('parent', 'bridge', 'lag')),
+ (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
+ (_('Wireless'), (
'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'wireless_lan_group', 'wireless_lans',
)),
)
@@ -1320,14 +1447,14 @@ class InterfaceBulkEditForm(
if not self.cleaned_data['mode']:
if self.cleaned_data['untagged_vlan']:
- raise forms.ValidationError({'untagged_vlan': "Interface mode must be specified to assign VLANs"})
+ raise forms.ValidationError({'untagged_vlan': _("Interface mode must be specified to assign VLANs")})
elif self.cleaned_data['tagged_vlans']:
- raise forms.ValidationError({'tagged_vlans': "Interface mode must be specified to assign VLANs"})
+ raise forms.ValidationError({'tagged_vlans': _("Interface mode must be specified to assign VLANs")})
# Untagged interfaces cannot be assigned tagged VLANs
elif self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and self.cleaned_data['tagged_vlans']:
raise forms.ValidationError({
- 'mode': "An access interface cannot have tagged VLANs assigned."
+ 'mode': _("An access interface cannot have tagged VLANs assigned.")
})
# Remove all tagged VLAN assignments from "tagged all" interfaces
@@ -1340,6 +1467,7 @@ class FrontPortBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1356,6 +1484,7 @@ class RearPortBulkEditForm(
ComponentBulkEditForm
):
mark_connected = forms.NullBooleanField(
+ label=_('Mark connected'),
required=False,
widget=BulkEditNullBooleanSelect
)
@@ -1394,14 +1523,17 @@ class InventoryItemBulkEditForm(
NetBoxModelBulkEditForm
):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
required=False
)
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
@@ -1419,9 +1551,11 @@ class InventoryItemBulkEditForm(
class InventoryItemRoleBulkEditForm(NetBoxModelBulkEditForm):
color = ColorField(
+ label=_('Color'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -1435,14 +1569,17 @@ class InventoryItemRoleBulkEditForm(NetBoxModelBulkEditForm):
class VirtualDeviceContextBulkEditForm(NetBoxModelBulkEditForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
required=False,
choices=add_blank_choice(VirtualDeviceContextStatusChoices)
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
diff --git a/netbox/dcim/forms/bulk_import.py b/netbox/dcim/forms/bulk_import.py
index d3acbc716..85d2b88bd 100644
--- a/netbox/dcim/forms/bulk_import.py
+++ b/netbox/dcim/forms/bulk_import.py
@@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms.array import SimpleArrayField
from django.core.exceptions import ObjectDoesNotExist
from django.utils.safestring import mark_safe
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import *
from dcim.constants import *
@@ -56,6 +56,7 @@ __all__ = (
class RegionImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=Region.objects.all(),
required=False,
to_field_name='name',
@@ -69,6 +70,7 @@ class RegionImportForm(NetBoxModelImportForm):
class SiteGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=SiteGroup.objects.all(),
required=False,
to_field_name='name',
@@ -82,22 +84,26 @@ class SiteGroupImportForm(NetBoxModelImportForm):
class SiteImportForm(NetBoxModelImportForm):
status = CSVChoiceField(
+ label=_('Status'),
choices=SiteStatusChoices,
help_text=_('Operational status')
)
region = CSVModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned region')
)
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=SiteGroup.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned group')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -119,11 +125,13 @@ class SiteImportForm(NetBoxModelImportForm):
class LocationImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
help_text=_('Assigned site')
)
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=Location.objects.all(),
required=False,
to_field_name='name',
@@ -133,10 +141,12 @@ class LocationImportForm(NetBoxModelImportForm):
}
)
status = CSVChoiceField(
+ label=_('Status'),
choices=LocationStatusChoices,
help_text=_('Operational status')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -161,45 +171,54 @@ class RackRoleImportForm(NetBoxModelImportForm):
class RackImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name'
)
location = CSVModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
to_field_name='name'
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Name of assigned tenant')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=RackStatusChoices,
help_text=_('Operational status')
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=RackRole.objects.all(),
required=False,
to_field_name='name',
help_text=_('Name of assigned role')
)
type = CSVChoiceField(
+ label=_('Type'),
choices=RackTypeChoices,
required=False,
help_text=_('Rack type')
)
width = forms.ChoiceField(
+ label=_('Width'),
choices=RackWidthChoices,
help_text=_('Rail-to-rail width (in inches)')
)
outer_unit = CSVChoiceField(
+ label=_('Outer unit'),
choices=RackDimensionUnitChoices,
required=False,
help_text=_('Unit for outer dimensions')
)
weight_unit = CSVChoiceField(
+ label=_('Weight unit'),
choices=WeightUnitChoices,
required=False,
help_text=_('Unit for rack weights')
@@ -225,27 +244,32 @@ class RackImportForm(NetBoxModelImportForm):
class RackReservationImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
help_text=_('Parent site')
)
location = CSVModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
to_field_name='name',
required=False,
help_text=_("Rack's location (if any)")
)
rack = CSVModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
to_field_name='name',
help_text=_('Rack')
)
units = SimpleArrayField(
+ label=_('Units'),
base_field=forms.IntegerField(),
required=True,
help_text=_('Comma-separated list of individual unit numbers')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -282,21 +306,25 @@ class ManufacturerImportForm(NetBoxModelImportForm):
class DeviceTypeImportForm(NetBoxModelImportForm):
manufacturer = forms.ModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
to_field_name='name',
help_text=_('The manufacturer which produces this device type')
)
default_platform = forms.ModelChoiceField(
+ label=_('Default platform'),
queryset=Platform.objects.all(),
to_field_name='name',
required=False,
help_text=_('The default platform for devices of this type (optional)')
)
weight = forms.DecimalField(
+ label=_('Weight'),
required=False,
help_text=_('Device weight'),
)
weight_unit = CSVChoiceField(
+ label=_('Weight unit'),
choices=WeightUnitChoices,
required=False,
help_text=_('Unit for device weight')
@@ -312,14 +340,17 @@ class DeviceTypeImportForm(NetBoxModelImportForm):
class ModuleTypeImportForm(NetBoxModelImportForm):
manufacturer = forms.ModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
to_field_name='name'
)
weight = forms.DecimalField(
+ label=_('Weight'),
required=False,
help_text=_('Module weight'),
)
weight_unit = CSVChoiceField(
+ label=_('Weight unit'),
choices=WeightUnitChoices,
required=False,
help_text=_('Unit for module weight')
@@ -332,6 +363,7 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
class DeviceRoleImportForm(NetBoxModelImportForm):
config_template = CSVModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
to_field_name='name',
required=False,
@@ -350,12 +382,14 @@ class DeviceRoleImportForm(NetBoxModelImportForm):
class PlatformImportForm(NetBoxModelImportForm):
slug = SlugField()
manufacturer = CSVModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False,
to_field_name='name',
help_text=_('Limit platform assignments to this manufacturer')
)
config_template = CSVModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
to_field_name='name',
required=False,
@@ -371,43 +405,51 @@ class PlatformImportForm(NetBoxModelImportForm):
class BaseDeviceImportForm(NetBoxModelImportForm):
device_role = CSVModelChoiceField(
+ label=_('Device role'),
queryset=DeviceRole.objects.all(),
to_field_name='name',
help_text=_('Assigned role')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
manufacturer = CSVModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
to_field_name='name',
help_text=_('Device type manufacturer')
)
device_type = CSVModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all(),
to_field_name='model',
help_text=_('Device type model')
)
platform = CSVModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned platform')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=DeviceStatusChoices,
help_text=_('Operational status')
)
virtual_chassis = CSVModelChoiceField(
+ label=_('Virtual chassis'),
queryset=VirtualChassis.objects.all(),
to_field_name='name',
required=False,
help_text=_('Virtual chassis')
)
cluster = CSVModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
to_field_name='name',
required=False,
@@ -430,45 +472,53 @@ class BaseDeviceImportForm(NetBoxModelImportForm):
class DeviceImportForm(BaseDeviceImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
help_text=_('Assigned site')
)
location = CSVModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
to_field_name='name',
required=False,
help_text=_("Assigned location (if any)")
)
rack = CSVModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
to_field_name='name',
required=False,
help_text=_("Assigned rack (if any)")
)
face = CSVChoiceField(
+ label=_('Face'),
choices=DeviceFaceChoices,
required=False,
help_text=_('Mounted rack face')
)
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=Device.objects.all(),
to_field_name='name',
required=False,
help_text=_('Parent device (for child devices)')
)
device_bay = CSVModelChoiceField(
+ label=_('Device bay'),
queryset=DeviceBay.objects.all(),
to_field_name='name',
required=False,
help_text=_('Device bay in which this device is installed (for child devices)')
)
airflow = CSVChoiceField(
+ label=_('Airflow'),
choices=DeviceAirflowChoices,
required=False,
help_text=_('Airflow direction')
)
config_template = CSVModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
to_field_name='name',
required=False,
@@ -523,29 +573,35 @@ class DeviceImportForm(BaseDeviceImportForm):
class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name',
help_text=_('The device in which this module is installed')
)
module_bay = CSVModelChoiceField(
+ label=_('Module bay'),
queryset=ModuleBay.objects.all(),
to_field_name='name',
help_text=_('The module bay in which this module is installed')
)
module_type = CSVModelChoiceField(
+ label=_('Module type'),
queryset=ModuleType.objects.all(),
to_field_name='model',
help_text=_('The type of module')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=ModuleStatusChoices,
help_text=_('Operational status')
)
replicate_components = forms.BooleanField(
+ label=_('Replicate components'),
required=False,
help_text=_('Automatically populate components associated with this module type (enabled by default)')
)
adopt_components = forms.BooleanField(
+ label=_('Adopt components'),
required=False,
help_text=_('Adopt already existing components')
)
@@ -579,15 +635,18 @@ class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm):
class ConsolePortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
type = CSVChoiceField(
+ label=_('Type'),
choices=ConsolePortTypeChoices,
required=False,
help_text=_('Port type')
)
speed = CSVTypedChoiceField(
+ label=_('Speed'),
choices=ConsolePortSpeedChoices,
coerce=int,
empty_value=None,
@@ -602,15 +661,18 @@ class ConsolePortImportForm(NetBoxModelImportForm):
class ConsoleServerPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
type = CSVChoiceField(
+ label=_('Type'),
choices=ConsolePortTypeChoices,
required=False,
help_text=_('Port type')
)
speed = CSVTypedChoiceField(
+ label=_('Speed'),
choices=ConsolePortSpeedChoices,
coerce=int,
empty_value=None,
@@ -625,10 +687,12 @@ class ConsoleServerPortImportForm(NetBoxModelImportForm):
class PowerPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
type = CSVChoiceField(
+ label=_('Type'),
choices=PowerPortTypeChoices,
required=False,
help_text=_('Port type')
@@ -643,21 +707,25 @@ class PowerPortImportForm(NetBoxModelImportForm):
class PowerOutletImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
type = CSVChoiceField(
+ label=_('Type'),
choices=PowerOutletTypeChoices,
required=False,
help_text=_('Outlet type')
)
power_port = CSVModelChoiceField(
+ label=_('Power port'),
queryset=PowerPort.objects.all(),
required=False,
to_field_name='name',
help_text=_('Local power port which feeds this outlet')
)
feed_leg = CSVChoiceField(
+ label=_('Feed lag'),
choices=PowerOutletFeedLegChoices,
required=False,
help_text=_('Electrical phase (for three-phase circuits)')
@@ -692,63 +760,75 @@ class PowerOutletImportForm(NetBoxModelImportForm):
class InterfaceImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=Interface.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent interface')
)
bridge = CSVModelChoiceField(
+ label=_('Bridge'),
queryset=Interface.objects.all(),
required=False,
to_field_name='name',
help_text=_('Bridged interface')
)
lag = CSVModelChoiceField(
+ label=_('Lag'),
queryset=Interface.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent LAG interface')
)
vdcs = CSVModelMultipleChoiceField(
+ label=_('Vdcs'),
queryset=VirtualDeviceContext.objects.all(),
required=False,
to_field_name='name',
- help_text='VDC names separated by commas, encased with double quotes (e.g. "vdc1, vdc2, vdc3")'
+ help_text=_('VDC names separated by commas, encased with double quotes (e.g. "vdc1, vdc2, vdc3")')
)
type = CSVChoiceField(
+ label=_('Type'),
choices=InterfaceTypeChoices,
help_text=_('Physical medium')
)
duplex = CSVChoiceField(
+ label=_('Duplex'),
choices=InterfaceDuplexChoices,
required=False
)
poe_mode = CSVChoiceField(
+ label=_('Poe mode'),
choices=InterfacePoEModeChoices,
required=False,
help_text=_('PoE mode')
)
poe_type = CSVChoiceField(
+ label=_('Poe type'),
choices=InterfacePoETypeChoices,
required=False,
help_text=_('PoE type')
)
mode = CSVChoiceField(
+ label=_('Mode'),
choices=InterfaceModeChoices,
required=False,
help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)')
)
vrf = CSVModelChoiceField(
+ label=_('VRF'),
queryset=VRF.objects.all(),
required=False,
to_field_name='rd',
help_text=_('Assigned VRF')
)
rf_role = CSVChoiceField(
+ label=_('Rf role'),
choices=WirelessRoleChoices,
required=False,
help_text=_('Wireless role (AP/station)')
@@ -792,15 +872,18 @@ class InterfaceImportForm(NetBoxModelImportForm):
class FrontPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
rear_port = CSVModelChoiceField(
+ label=_('Rear port'),
queryset=RearPort.objects.all(),
to_field_name='name',
help_text=_('Corresponding rear port')
)
type = CSVChoiceField(
+ label=_('Type'),
choices=PortTypeChoices,
help_text=_('Physical medium classification')
)
@@ -837,10 +920,12 @@ class FrontPortImportForm(NetBoxModelImportForm):
class RearPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
type = CSVChoiceField(
+ label=_('Type'),
help_text=_('Physical medium classification'),
choices=PortTypeChoices,
)
@@ -852,6 +937,7 @@ class RearPortImportForm(NetBoxModelImportForm):
class ModuleBayImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
@@ -863,10 +949,12 @@ class ModuleBayImportForm(NetBoxModelImportForm):
class DeviceBayImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
installed_device = CSVModelChoiceField(
+ label=_('Installed device'),
queryset=Device.objects.all(),
required=False,
to_field_name='name',
@@ -909,32 +997,38 @@ class DeviceBayImportForm(NetBoxModelImportForm):
class InventoryItemImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name'
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
to_field_name='name',
required=False
)
manufacturer = CSVModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
to_field_name='name',
required=False
)
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=Device.objects.all(),
to_field_name='name',
required=False,
help_text=_('Parent inventory item')
)
component_type = CSVContentTypeField(
+ label=_('Component type'),
queryset=ContentType.objects.all(),
limit_choices_to=MODULAR_COMPONENT_MODELS,
required=False,
help_text=_('Component Type')
)
component_name = forms.CharField(
+ label=_('Compnent name'),
required=False,
help_text=_('Component Name')
)
@@ -1002,52 +1096,62 @@ class InventoryItemRoleImportForm(NetBoxModelImportForm):
class CableImportForm(NetBoxModelImportForm):
# Termination A
side_a_device = CSVModelChoiceField(
+ label=_('Side a device'),
queryset=Device.objects.all(),
to_field_name='name',
help_text=_('Side A device')
)
side_a_type = CSVContentTypeField(
+ label=_('Side a type'),
queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS,
help_text=_('Side A type')
)
side_a_name = forms.CharField(
+ label=_('Side a name'),
help_text=_('Side A component name')
)
# Termination B
side_b_device = CSVModelChoiceField(
+ label=_('Side b device'),
queryset=Device.objects.all(),
to_field_name='name',
help_text=_('Side B device')
)
side_b_type = CSVContentTypeField(
+ label=_('Side b type'),
queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS,
help_text=_('Side B type')
)
side_b_name = forms.CharField(
+ label=_('Side b name'),
help_text=_('Side B component name')
)
# Cable attributes
status = CSVChoiceField(
+ label=_('Status'),
choices=LinkStatusChoices,
required=False,
help_text=_('Connection status')
)
type = CSVChoiceField(
+ label=_('Type'),
choices=CableTypeChoices,
required=False,
help_text=_('Physical medium classification')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
length_unit = CSVChoiceField(
+ label=_('Length unit'),
choices=CableLengthUnitChoices,
required=False,
help_text=_('Length unit')
@@ -1110,6 +1214,7 @@ class CableImportForm(NetBoxModelImportForm):
class VirtualChassisImportForm(NetBoxModelImportForm):
master = CSVModelChoiceField(
+ label=_('Master'),
queryset=Device.objects.all(),
to_field_name='name',
required=False,
@@ -1127,11 +1232,13 @@ class VirtualChassisImportForm(NetBoxModelImportForm):
class PowerPanelImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
help_text=_('Name of parent site')
)
location = CSVModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
to_field_name='name'
@@ -1153,22 +1260,26 @@ class PowerPanelImportForm(NetBoxModelImportForm):
class PowerFeedImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
help_text=_('Assigned site')
)
power_panel = CSVModelChoiceField(
+ label=_('Power panel'),
queryset=PowerPanel.objects.all(),
to_field_name='name',
help_text=_('Upstream power panel')
)
location = CSVModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
to_field_name='name',
required=False,
help_text=_("Rack's location (if any)")
)
rack = CSVModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
to_field_name='name',
required=False,
@@ -1181,18 +1292,22 @@ class PowerFeedImportForm(NetBoxModelImportForm):
help_text=_('Assigned tenant')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=PowerFeedStatusChoices,
help_text=_('Operational status')
)
type = CSVChoiceField(
+ label=_('Type'),
choices=PowerFeedTypeChoices,
help_text=_('Primary or redundant')
)
supply = CSVChoiceField(
+ label=_('Supply'),
choices=PowerFeedSupplyChoices,
help_text=_('Supply type (AC/DC)')
)
phase = CSVChoiceField(
+ label=_('Phase'),
choices=PowerFeedPhaseChoices,
help_text=_('Single or three-phase')
)
@@ -1228,11 +1343,13 @@ class PowerFeedImportForm(NetBoxModelImportForm):
class VirtualDeviceContextImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name',
help_text='Assigned role'
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
diff --git a/netbox/dcim/forms/common.py b/netbox/dcim/forms/common.py
index 064a9a80b..77543af12 100644
--- a/netbox/dcim/forms/common.py
+++ b/netbox/dcim/forms/common.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import *
from dcim.constants import *
@@ -47,7 +47,7 @@ class InterfaceCommonForm(forms.Form):
# Untagged interfaces cannot be assigned tagged VLANs
if self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and tagged_vlans:
raise forms.ValidationError({
- 'mode': "An access interface cannot have tagged VLANs assigned."
+ 'mode': _("An access interface cannot have tagged VLANs assigned.")
})
# Remove all tagged VLAN assignments from "tagged all" interfaces
@@ -61,8 +61,10 @@ class InterfaceCommonForm(forms.Form):
if invalid_vlans:
raise forms.ValidationError({
- 'tagged_vlans': f"The tagged VLANs ({', '.join(invalid_vlans)}) must belong to the same site as "
- f"the interface's parent device/VM, or they must be global"
+ 'tagged_vlans': _(
+ "The tagged VLANs ({vlans}) must belong to the same site as the interface's parent device/VM, "
+ "or they must be global"
+ ).format(vlans=', '.join(invalid_vlans))
})
@@ -105,7 +107,7 @@ class ModuleCommonForm(forms.Form):
# Installing modules with placeholders require that the bay has a position value
if MODULE_TOKEN in template.name and not module_bay.position:
raise forms.ValidationError(
- "Cannot install module with placeholder values in a module bay with no position defined"
+ _("Cannot install module with placeholder values in a module bay with no position defined.")
)
resolved_name = template.name.replace(MODULE_TOKEN, module_bay.position)
@@ -114,12 +116,17 @@ class ModuleCommonForm(forms.Form):
# It is not possible to adopt components already belonging to a module
if adopt_components and existing_item and existing_item.module:
raise forms.ValidationError(
- f"Cannot adopt {template.component_model.__name__} '{resolved_name}' as it already belongs "
- f"to a module"
+ _("Cannot adopt {name} '{resolved_name}' as it already belongs to a module").format(
+ name=template.component_model.__name__,
+ resolved_name=resolved_name
+ )
)
# If we are not adopting components we error if the component exists
if not adopt_components and resolved_name in installed_components:
raise forms.ValidationError(
- f"{template.component_model.__name__} - {resolved_name} already exists"
+ _("{name} - {resolved_name} already exists").format(
+ name=template.component_model.__name__,
+ resolved_name=resolved_name
+ )
)
diff --git a/netbox/dcim/forms/connections.py b/netbox/dcim/forms/connections.py
index 8e3dcdc68..854c5ebed 100644
--- a/netbox/dcim/forms/connections.py
+++ b/netbox/dcim/forms/connections.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from circuits.models import Circuit, CircuitTermination
from dcim.models import *
diff --git a/netbox/dcim/forms/filtersets.py b/netbox/dcim/forms/filtersets.py
index f0ac017fa..3efbfb974 100644
--- a/netbox/dcim/forms/filtersets.py
+++ b/netbox/dcim/forms/filtersets.py
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.auth import get_user_model
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import *
from dcim.constants import *
@@ -56,9 +56,11 @@ __all__ = (
class DeviceComponentFilterForm(NetBoxModelFilterSetForm):
name = forms.CharField(
+ label=_('Name'),
required=False
)
label = forms.CharField(
+ label=_('Label'),
required=False
)
region_id = DynamicModelMultipleChoiceField(
@@ -130,7 +132,7 @@ class RegionFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Region
fieldsets = (
(None, ('q', 'filter_id', 'tag', 'parent_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group'))
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
)
parent_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -144,7 +146,7 @@ class SiteGroupFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = SiteGroup
fieldsets = (
(None, ('q', 'filter_id', 'tag', 'parent_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group'))
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
)
parent_id = DynamicModelMultipleChoiceField(
queryset=SiteGroup.objects.all(),
@@ -158,11 +160,12 @@ class SiteFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
model = Site
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('status', 'region_id', 'group_id', 'asn_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Attributes'), ('status', 'region_id', 'group_id', 'asn_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=SiteStatusChoices,
required=False
)
@@ -188,9 +191,9 @@ class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelF
model = Location
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('region_id', 'site_group_id', 'site_id', 'parent_id', 'status')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Attributes'), ('region_id', 'site_group_id', 'site_id', 'parent_id', 'status')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -221,6 +224,7 @@ class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelF
label=_('Parent')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=LocationStatusChoices,
required=False
)
@@ -236,12 +240,12 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
model = Rack
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')),
- ('Function', ('status', 'role_id')),
- ('Hardware', ('type', 'width', 'serial', 'asset_tag')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
- ('Weight', ('weight', 'max_weight', 'weight_unit')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
+ (_('Function'), ('status', 'role_id')),
+ (_('Hardware'), ('type', 'width', 'serial', 'asset_tag')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
+ (_('Weight'), ('weight', 'max_weight', 'weight_unit')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -271,14 +275,17 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
label=_('Location')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=RackStatusChoices,
required=False
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=RackTypeChoices,
required=False
)
width = forms.MultipleChoiceField(
+ label=_('Width'),
choices=RackWidthChoices,
required=False
)
@@ -289,21 +296,26 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
label=_('Role')
)
serial = forms.CharField(
+ label=_('Serial'),
required=False
)
asset_tag = forms.CharField(
+ label=_('Asset tag'),
required=False
)
tag = TagFilterField(model)
weight = forms.DecimalField(
+ label=_('Weight'),
required=False,
min_value=1
)
max_weight = forms.IntegerField(
+ label=_('Max weight'),
required=False,
min_value=1
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False
)
@@ -312,12 +324,12 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
class RackElevationFilterForm(RackFilterForm):
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'id')),
- ('Function', ('status', 'role_id')),
- ('Hardware', ('type', 'width', 'serial', 'asset_tag')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
- ('Weight', ('weight', 'max_weight', 'weight_unit')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'id')),
+ (_('Function'), ('status', 'role_id')),
+ (_('Hardware'), ('type', 'width', 'serial', 'asset_tag')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
+ (_('Weight'), ('weight', 'max_weight', 'weight_unit')),
)
id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(),
@@ -334,9 +346,9 @@ class RackReservationFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = RackReservation
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('User', ('user_id',)),
- ('Rack', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('User'), ('user_id',)),
+ (_('Rack'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -390,7 +402,7 @@ class ManufacturerFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Manufacturer
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Contacts', ('contact', 'contact_role', 'contact_group'))
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
)
tag = TagFilterField(model)
@@ -399,13 +411,13 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
model = DeviceType
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Hardware', ('manufacturer_id', 'default_platform_id', 'part_number', 'subdevice_role', 'airflow')),
- ('Images', ('has_front_image', 'has_rear_image')),
- ('Components', (
+ (_('Hardware'), ('manufacturer_id', 'default_platform_id', 'part_number', 'subdevice_role', 'airflow')),
+ (_('Images'), ('has_front_image', 'has_rear_image')),
+ (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
'pass_through_ports', 'device_bays', 'module_bays', 'inventory_items',
)),
- ('Weight', ('weight', 'weight_unit')),
+ (_('Weight'), ('weight', 'weight_unit')),
)
manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),
@@ -418,98 +430,103 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
label=_('Default platform')
)
part_number = forms.CharField(
+ label=_('Part number'),
required=False
)
subdevice_role = forms.MultipleChoiceField(
+ label=_('Subdevice role'),
choices=add_blank_choice(SubdeviceRoleChoices),
required=False
)
airflow = forms.MultipleChoiceField(
+ label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices),
required=False
)
has_front_image = forms.NullBooleanField(
required=False,
- label='Has a front image',
+ label=_('Has a front image'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
has_rear_image = forms.NullBooleanField(
required=False,
- label='Has a rear image',
+ label=_('Has a rear image'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
console_ports = forms.NullBooleanField(
required=False,
- label='Has console ports',
+ label=_('Has console ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
console_server_ports = forms.NullBooleanField(
required=False,
- label='Has console server ports',
+ label=_('Has console server ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_ports = forms.NullBooleanField(
required=False,
- label='Has power ports',
+ label=_('Has power ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_outlets = forms.NullBooleanField(
required=False,
- label='Has power outlets',
+ label=_('Has power outlets'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
interfaces = forms.NullBooleanField(
required=False,
- label='Has interfaces',
+ label=_('Has interfaces'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
pass_through_ports = forms.NullBooleanField(
required=False,
- label='Has pass-through ports',
+ label=_('Has pass-through ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
device_bays = forms.NullBooleanField(
required=False,
- label='Has device bays',
+ label=_('Has device bays'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
module_bays = forms.NullBooleanField(
required=False,
- label='Has module bays',
+ label=_('Has module bays'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
inventory_items = forms.NullBooleanField(
required=False,
- label='Has inventory items',
+ label=_('Has inventory items'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
tag = TagFilterField(model)
weight = forms.DecimalField(
+ label=_('Weight'),
required=False
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False
)
@@ -519,12 +536,12 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
model = ModuleType
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Hardware', ('manufacturer_id', 'part_number')),
- ('Components', (
+ (_('Hardware'), ('manufacturer_id', 'part_number')),
+ (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
'pass_through_ports',
)),
- ('Weight', ('weight', 'weight_unit')),
+ (_('Weight'), ('weight', 'weight_unit')),
)
manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),
@@ -533,55 +550,58 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
fetch_trigger='open'
)
part_number = forms.CharField(
+ label=_('Part number'),
required=False
)
console_ports = forms.NullBooleanField(
required=False,
- label='Has console ports',
+ label=_('Has console ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
console_server_ports = forms.NullBooleanField(
required=False,
- label='Has console server ports',
+ label=_('Has console server ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_ports = forms.NullBooleanField(
required=False,
- label='Has power ports',
+ label=_('Has power ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_outlets = forms.NullBooleanField(
required=False,
- label='Has power outlets',
+ label=_('Has power outlets'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
interfaces = forms.NullBooleanField(
required=False,
- label='Has interfaces',
+ label=_('Has interfaces'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
pass_through_ports = forms.NullBooleanField(
required=False,
- label='Has pass-through ports',
+ label=_('Has pass-through ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
tag = TagFilterField(model)
weight = forms.DecimalField(
+ label=_('Weight'),
required=False
)
weight_unit = forms.ChoiceField(
+ label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices),
required=False
)
@@ -621,15 +641,17 @@ class DeviceFilterForm(
model = Device
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Operation', ('status', 'role_id', 'airflow', 'serial', 'asset_tag', 'mac_address')),
- ('Hardware', ('manufacturer_id', 'device_type_id', 'platform_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
- ('Components', (
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Operation'), ('status', 'role_id', 'airflow', 'serial', 'asset_tag', 'mac_address')),
+ (_('Hardware'), ('manufacturer_id', 'device_type_id', 'platform_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
+ (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'pass_through_ports',
)),
- ('Miscellaneous', ('has_primary_ip', 'has_oob_ip', 'virtual_chassis_member', 'config_template_id', 'local_context_data'))
+ (_('Miscellaneous'), (
+ 'has_primary_ip', 'has_oob_ip', 'virtual_chassis_member', 'config_template_id', 'local_context_data',
+ ))
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -694,22 +716,26 @@ class DeviceFilterForm(
label=_('Platform')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=DeviceStatusChoices,
required=False
)
airflow = forms.MultipleChoiceField(
+ label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices),
required=False
)
serial = forms.CharField(
+ label=_('Serial'),
required=False
)
asset_tag = forms.CharField(
+ label=_('Asset tag'),
required=False
)
mac_address = forms.CharField(
required=False,
- label='MAC address'
+ label=_('MAC address')
)
config_template_id = DynamicModelMultipleChoiceField(
queryset=ConfigTemplate.objects.all(),
@@ -718,7 +744,7 @@ class DeviceFilterForm(
)
has_primary_ip = forms.NullBooleanField(
required=False,
- label='Has a primary IP',
+ label=_('Has a primary IP'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
@@ -732,49 +758,49 @@ class DeviceFilterForm(
)
virtual_chassis_member = forms.NullBooleanField(
required=False,
- label='Virtual chassis member',
+ label=_('Virtual chassis member'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
console_ports = forms.NullBooleanField(
required=False,
- label='Has console ports',
+ label=_('Has console ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
console_server_ports = forms.NullBooleanField(
required=False,
- label='Has console server ports',
+ label=_('Has console server ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_ports = forms.NullBooleanField(
required=False,
- label='Has power ports',
+ label=_('Has power ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
power_outlets = forms.NullBooleanField(
required=False,
- label='Has power outlets',
+ label=_('Has power outlets'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
interfaces = forms.NullBooleanField(
required=False,
- label='Has interfaces',
+ label=_('Has interfaces'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
pass_through_ports = forms.NullBooleanField(
required=False,
- label='Has pass-through ports',
+ label=_('Has pass-through ports'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
@@ -789,8 +815,8 @@ class VirtualDeviceContextFilterForm(
model = VirtualDeviceContext
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('device', 'status', 'has_primary_ip')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Attributes'), ('device', 'status', 'has_primary_ip')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
device = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(),
@@ -799,12 +825,13 @@ class VirtualDeviceContextFilterForm(
fetch_trigger='open'
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
required=False,
choices=add_blank_choice(VirtualDeviceContextStatusChoices)
)
has_primary_ip = forms.NullBooleanField(
required=False,
- label='Has a primary IP',
+ label=_('Has a primary IP'),
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
@@ -816,7 +843,7 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
model = Module
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Hardware', ('manufacturer_id', 'module_type_id', 'status', 'serial', 'asset_tag')),
+ (_('Hardware'), ('manufacturer_id', 'module_type_id', 'status', 'serial', 'asset_tag')),
)
manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),
@@ -834,13 +861,16 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
fetch_trigger='open'
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=ModuleStatusChoices,
required=False
)
serial = forms.CharField(
+ label=_('Serial'),
required=False
)
asset_tag = forms.CharField(
+ label=_('Asset tag'),
required=False
)
tag = TagFilterField(model)
@@ -850,8 +880,8 @@ class VirtualChassisFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VirtualChassis
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -879,9 +909,9 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Cable
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('site_id', 'location_id', 'rack_id', 'device_id')),
- ('Attributes', ('type', 'status', 'color', 'length', 'length_unit')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Location'), ('site_id', 'location_id', 'rack_id', 'device_id')),
+ (_('Attributes'), ('type', 'status', 'color', 'length', 'length_unit')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -927,20 +957,25 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Device')
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=add_blank_choice(CableTypeChoices),
required=False
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
required=False,
choices=add_blank_choice(LinkStatusChoices)
)
color = ColorField(
+ label=_('Color'),
required=False
)
length = forms.IntegerField(
+ label=_('Length'),
required=False
)
length_unit = forms.ChoiceField(
+ label=_('Length unit'),
choices=add_blank_choice(CableLengthUnitChoices),
required=False
)
@@ -951,8 +986,8 @@ class PowerPanelFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = PowerPanel
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -989,9 +1024,9 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = PowerFeed
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'power_panel_id', 'rack_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Attributes', ('status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'power_panel_id', 'rack_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Attributes'), ('status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -1030,28 +1065,35 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Rack')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=PowerFeedStatusChoices,
required=False
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(PowerFeedTypeChoices),
required=False
)
supply = forms.ChoiceField(
+ label=_('Supply'),
choices=add_blank_choice(PowerFeedSupplyChoices),
required=False
)
phase = forms.ChoiceField(
+ label=_('Phase'),
choices=add_blank_choice(PowerFeedPhaseChoices),
required=False
)
voltage = forms.IntegerField(
+ label=_('Voltage'),
required=False
)
amperage = forms.IntegerField(
+ label=_('Amperage'),
required=False
)
max_utilization = forms.IntegerField(
+ label=_('Max utilization'),
required=False
)
tag = TagFilterField(model)
@@ -1063,12 +1105,14 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class CabledFilterForm(forms.Form):
cabled = forms.NullBooleanField(
+ label=_('Cabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
occupied = forms.NullBooleanField(
+ label=_('Occupied'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -1078,6 +1122,7 @@ class CabledFilterForm(forms.Form):
class PathEndpointFilterForm(CabledFilterForm):
connected = forms.NullBooleanField(
+ label=_('Connected'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -1089,16 +1134,18 @@ class ConsolePortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = ConsolePort
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type', 'speed')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Connection', ('cabled', 'connected', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type', 'speed')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Connection'), ('cabled', 'connected', 'occupied')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=ConsolePortTypeChoices,
required=False
)
speed = forms.MultipleChoiceField(
+ label=_('Speed'),
choices=ConsolePortSpeedChoices,
required=False
)
@@ -1109,16 +1156,18 @@ class ConsoleServerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterF
model = ConsoleServerPort
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type', 'speed')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Connection', ('cabled', 'connected', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type', 'speed')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Connection'), ('cabled', 'connected', 'occupied')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=ConsolePortTypeChoices,
required=False
)
speed = forms.MultipleChoiceField(
+ label=_('Speed'),
choices=ConsolePortSpeedChoices,
required=False
)
@@ -1129,12 +1178,13 @@ class PowerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = PowerPort
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Connection', ('cabled', 'connected', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Connection'), ('cabled', 'connected', 'occupied')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=PowerPortTypeChoices,
required=False
)
@@ -1145,12 +1195,13 @@ class PowerOutletFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = PowerOutlet
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Connection', ('cabled', 'connected', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Connection'), ('cabled', 'connected', 'occupied')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=PowerOutletTypeChoices,
required=False
)
@@ -1161,13 +1212,13 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = Interface
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only')),
- ('Addressing', ('vrf_id', 'l2vpn_id', 'mac_address', 'wwn')),
- ('PoE', ('poe_mode', 'poe_type')),
- ('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id', 'vdc_id')),
- ('Connection', ('cabled', 'connected', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only')),
+ (_('Addressing'), ('vrf_id', 'l2vpn_id', 'mac_address', 'wwn')),
+ (_('PoE'), ('poe_mode', 'poe_type')),
+ (_('Wireless'), ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id', 'vdc_id')),
+ (_('Connection'), ('cabled', 'connected', 'occupied')),
)
vdc_id = DynamicModelMultipleChoiceField(
queryset=VirtualDeviceContext.objects.all(),
@@ -1178,30 +1229,36 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
label=_('Virtual Device Context')
)
kind = forms.MultipleChoiceField(
+ label=_('Kind'),
choices=InterfaceKindChoices,
required=False
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=InterfaceTypeChoices,
required=False
)
speed = forms.IntegerField(
+ label=_('Speed'),
required=False,
widget=NumberWithOptions(
options=InterfaceSpeedChoices
)
)
duplex = forms.MultipleChoiceField(
+ label=_('Duplex'),
choices=InterfaceDuplexChoices,
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
mgmt_only = forms.NullBooleanField(
+ label=_('Mgmt only'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -1209,50 +1266,50 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
)
mac_address = forms.CharField(
required=False,
- label='MAC address'
+ label=_('MAC address')
)
wwn = forms.CharField(
required=False,
- label='WWN'
+ label=_('WWN')
)
poe_mode = forms.MultipleChoiceField(
choices=InterfacePoEModeChoices,
required=False,
- label='PoE mode'
+ label=_('PoE mode')
)
poe_type = forms.MultipleChoiceField(
choices=InterfacePoETypeChoices,
required=False,
- label='PoE type'
+ label=_('PoE type')
)
rf_role = forms.MultipleChoiceField(
choices=WirelessRoleChoices,
required=False,
- label='Wireless role'
+ label=_('Wireless role')
)
rf_channel = forms.MultipleChoiceField(
choices=WirelessChannelChoices,
required=False,
- label='Wireless channel'
+ label=_('Wireless channel')
)
rf_channel_frequency = forms.IntegerField(
required=False,
- label='Channel frequency (MHz)'
+ label=_('Channel frequency (MHz)')
)
rf_channel_width = forms.IntegerField(
required=False,
- label='Channel width (MHz)'
+ label=_('Channel width (MHz)')
)
tx_power = forms.IntegerField(
required=False,
- label='Transmit power (dBm)',
+ label=_('Transmit power (dBm)'),
min_value=0,
max_value=127
)
vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
required=False,
- label='VRF'
+ label=_('VRF')
)
l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(),
@@ -1265,17 +1322,19 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
class FrontPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type', 'color')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Cable', ('cabled', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type', 'color')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Cable'), ('cabled', 'occupied')),
)
model = FrontPort
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=PortTypeChoices,
required=False
)
color = ColorField(
+ label=_('Color'),
required=False
)
tag = TagFilterField(model)
@@ -1285,16 +1344,18 @@ class RearPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
model = RearPort
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'type', 'color')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
- ('Cable', ('cabled', 'occupied')),
+ (_('Attributes'), ('name', 'label', 'type', 'color')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Cable'), ('cabled', 'occupied')),
)
type = forms.MultipleChoiceField(
+ label=_('Type'),
choices=PortTypeChoices,
required=False
)
color = ColorField(
+ label=_('Color'),
required=False
)
tag = TagFilterField(model)
@@ -1304,12 +1365,13 @@ class ModuleBayFilterForm(DeviceComponentFilterForm):
model = ModuleBay
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'position')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Attributes'), ('name', 'label', 'position')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
)
tag = TagFilterField(model)
position = forms.CharField(
+ label=_('Position'),
required=False
)
@@ -1318,9 +1380,9 @@ class DeviceBayFilterForm(DeviceComponentFilterForm):
model = DeviceBay
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Attributes'), ('name', 'label')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
)
tag = TagFilterField(model)
@@ -1329,9 +1391,9 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
model = InventoryItem
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'label', 'role_id', 'manufacturer_id', 'serial', 'asset_tag', 'discovered')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
- ('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
+ (_('Attributes'), ('name', 'label', 'role_id', 'manufacturer_id', 'serial', 'asset_tag', 'discovered')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
+ (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
)
role_id = DynamicModelMultipleChoiceField(
queryset=InventoryItemRole.objects.all(),
@@ -1345,12 +1407,15 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
label=_('Manufacturer')
)
serial = forms.CharField(
+ label=_('Serial'),
required=False
)
asset_tag = forms.CharField(
+ label=_('Asset tag'),
required=False
)
discovered = forms.NullBooleanField(
+ label=_('Discovered'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
diff --git a/netbox/dcim/forms/formsets.py b/netbox/dcim/forms/formsets.py
index 6109a1575..0b9d89a5d 100644
--- a/netbox/dcim/forms/formsets.py
+++ b/netbox/dcim/forms/formsets.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import gettext_lazy as _
__all__ = (
'BaseVCMemberFormSet',
@@ -16,6 +17,8 @@ class BaseVCMemberFormSet(forms.BaseModelFormSet):
vc_position = form.cleaned_data.get('vc_position')
if vc_position:
if vc_position in vc_position_list:
- error_msg = f"A virtual chassis member already exists in position {vc_position}."
+ error_msg = _("A virtual chassis member already exists in position {vc_position}.").format(
+ vc_position=vc_position
+ )
form.add_error('vc_position', error_msg)
vc_position_list.append(vc_position)
diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py
index 4c382babc..4bdb19120 100644
--- a/netbox/dcim/forms/model_forms.py
+++ b/netbox/dcim/forms/model_forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from timezone_field import TimeZoneFormField
from dcim.choices import *
@@ -70,13 +70,14 @@ __all__ = (
class RegionForm(NetBoxModelForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=Region.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Region', (
+ (_('Region'), (
'parent', 'name', 'slug', 'description', 'tags',
)),
)
@@ -90,13 +91,14 @@ class RegionForm(NetBoxModelForm):
class SiteGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=SiteGroup.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Site Group', (
+ (_('Site Group'), (
'parent', 'name', 'slug', 'description', 'tags',
)),
)
@@ -110,10 +112,12 @@ class SiteGroupForm(NetBoxModelForm):
class SiteForm(TenancyForm, NetBoxModelForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=SiteGroup.objects.all(),
required=False
)
@@ -124,17 +128,18 @@ class SiteForm(TenancyForm, NetBoxModelForm):
)
slug = SlugField()
time_zone = TimeZoneFormField(
+ label=_('Time zone'),
choices=add_blank_choice(TimeZoneFormField().choices),
required=False
)
comments = CommentField()
fieldsets = (
- ('Site', (
+ (_('Site'), (
'name', 'slug', 'status', 'region', 'group', 'facility', 'asns', 'time_zone', 'description', 'tags',
)),
- ('Tenancy', ('tenant_group', 'tenant')),
- ('Contact Info', ('physical_address', 'shipping_address', 'latitude', 'longitude')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
+ (_('Contact Info'), ('physical_address', 'shipping_address', 'latitude', 'longitude')),
)
class Meta:
@@ -159,10 +164,12 @@ class SiteForm(TenancyForm, NetBoxModelForm):
class LocationForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
selector=True
)
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -172,8 +179,8 @@ class LocationForm(TenancyForm, NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Location', ('site', 'parent', 'name', 'slug', 'status', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Location'), ('site', 'parent', 'name', 'slug', 'status', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -187,7 +194,7 @@ class RackRoleForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Rack Role', (
+ (_('Rack Role'), (
'name', 'slug', 'color', 'description', 'tags',
)),
)
@@ -201,10 +208,12 @@ class RackRoleForm(NetBoxModelForm):
class RackForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
selector=True
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -212,6 +221,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
}
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=RackRole.objects.all(),
required=False
)
@@ -228,14 +238,17 @@ class RackForm(TenancyForm, NetBoxModelForm):
class RackReservationForm(TenancyForm, NetBoxModelForm):
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
selector=True
)
units = NumericArrayField(
+ label=_('Units'),
base_field=forms.IntegerField(),
help_text=_("Comma-separated list of numeric unit IDs. A range may be specified using a hyphen.")
)
user = forms.ModelChoiceField(
+ label=_('User'),
queryset=get_user_model().objects.order_by(
'username'
)
@@ -243,8 +256,8 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Reservation', ('rack', 'units', 'user', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Reservation'), ('rack', 'units', 'user', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -258,7 +271,7 @@ class ManufacturerForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Manufacturer', (
+ (_('Manufacturer'), (
'name', 'slug', 'description', 'tags',
)),
)
@@ -272,23 +285,26 @@ class ManufacturerForm(NetBoxModelForm):
class DeviceTypeForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all()
)
default_platform = DynamicModelChoiceField(
+ label=_('Default platform'),
queryset=Platform.objects.all(),
required=False
)
slug = SlugField(
+ label=_('Slug'),
slug_source='model'
)
comments = CommentField()
fieldsets = (
- ('Device Type', ('manufacturer', 'model', 'slug', 'default_platform', 'description', 'tags')),
- ('Chassis', (
+ (_('Device Type'), ('manufacturer', 'model', 'slug', 'default_platform', 'description', 'tags')),
+ (_('Chassis'), (
'u_height', 'is_full_depth', 'part_number', 'subdevice_role', 'airflow', 'weight', 'weight_unit',
)),
- ('Images', ('front_image', 'rear_image')),
+ (_('Images'), ('front_image', 'rear_image')),
)
class Meta:
@@ -310,13 +326,14 @@ class DeviceTypeForm(NetBoxModelForm):
class ModuleTypeForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all()
)
comments = CommentField()
fieldsets = (
- ('Module Type', ('manufacturer', 'model', 'part_number', 'description', 'tags')),
- ('Weight', ('weight', 'weight_unit'))
+ (_('Module Type'), ('manufacturer', 'model', 'part_number', 'description', 'tags')),
+ (_('Weight'), ('weight', 'weight_unit'))
)
class Meta:
@@ -328,13 +345,14 @@ class ModuleTypeForm(NetBoxModelForm):
class DeviceRoleForm(NetBoxModelForm):
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Device Role', (
+ (_('Device Role'), (
'name', 'slug', 'color', 'vm_role', 'config_template', 'description', 'tags',
)),
)
@@ -348,19 +366,22 @@ class DeviceRoleForm(NetBoxModelForm):
class PlatformForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
slug = SlugField(
+ label=_('Slug'),
max_length=64
)
fieldsets = (
- ('Platform', ('name', 'slug', 'manufacturer', 'config_template', 'description', 'tags')),
+ (_('Platform'), ('name', 'slug', 'manufacturer', 'config_template', 'description', 'tags')),
)
class Meta:
@@ -372,10 +393,12 @@ class PlatformForm(NetBoxModelForm):
class DeviceForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
selector=True
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -386,6 +409,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
}
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
query_params={
@@ -394,6 +418,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
}
)
position = forms.DecimalField(
+ label=_('Position'),
required=False,
help_text=_("The lowest-numbered unit occupied by the device"),
widget=APISelect(
@@ -405,17 +430,21 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
)
)
device_type = DynamicModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all(),
selector=True
)
device_role = DynamicModelChoiceField(
+ label=_('Device role'),
queryset=DeviceRole.objects.all()
)
platform = DynamicModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False
)
cluster = DynamicModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
required=False,
selector=True
@@ -426,6 +455,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
label=''
)
virtual_chassis = DynamicModelChoiceField(
+ label=_('Virtual chassis'),
queryset=VirtualChassis.objects.all(),
required=False,
selector=True
@@ -441,6 +471,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
help_text=_("The priority of the device in the virtual chassis")
)
config_template = DynamicModelChoiceField(
+ label=_('Config template'),
queryset=ConfigTemplate.objects.all(),
required=False
)
@@ -518,36 +549,41 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
class ModuleForm(ModuleCommonForm, NetBoxModelForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
initial_params={
'modulebays': '$module_bay'
}
)
module_bay = DynamicModelChoiceField(
+ label=_('Module bay'),
queryset=ModuleBay.objects.all(),
query_params={
'device_id': '$device'
}
)
module_type = DynamicModelChoiceField(
+ label=_('Module type'),
queryset=ModuleType.objects.all(),
selector=True
)
comments = CommentField()
replicate_components = forms.BooleanField(
+ label=_('Replicate components'),
required=False,
initial=True,
help_text=_("Automatically populate components associated with this module type")
)
adopt_components = forms.BooleanField(
+ label=_('Adopt components'),
required=False,
initial=False,
help_text=_("Adopt already existing components")
)
fieldsets = (
- ('Module', ('device', 'module_bay', 'module_type', 'status', 'description', 'tags')),
- ('Hardware', (
+ (_('Module'), ('device', 'module_bay', 'module_type', 'status', 'description', 'tags')),
+ (_('Hardware'), (
'serial', 'asset_tag', 'replicate_components', 'adopt_components',
)),
)
@@ -581,17 +617,19 @@ class CableForm(TenancyForm, NetBoxModelForm):
]
error_messages = {
'length': {
- 'max_value': 'Maximum length is 32767 (any unit)'
+ 'max_value': _('Maximum length is 32767 (any unit)')
}
}
class PowerPanelForm(NetBoxModelForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
selector=True
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
query_params={
@@ -613,10 +651,12 @@ class PowerPanelForm(NetBoxModelForm):
class PowerFeedForm(TenancyForm, NetBoxModelForm):
power_panel = DynamicModelChoiceField(
+ label=_('Power panel'),
queryset=PowerPanel.objects.all(),
selector=True
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
selector=True
@@ -624,9 +664,9 @@ class PowerFeedForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Power Feed', ('power_panel', 'rack', 'name', 'status', 'type', 'description', 'mark_connected', 'tags')),
- ('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Power Feed'), ('power_panel', 'rack', 'name', 'status', 'type', 'description', 'mark_connected', 'tags')),
+ (_('Characteristics'), ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -643,6 +683,7 @@ class PowerFeedForm(TenancyForm, NetBoxModelForm):
class VirtualChassisForm(NetBoxModelForm):
master = forms.ModelChoiceField(
+ label=_('Master'),
queryset=Device.objects.all(),
required=False,
)
@@ -706,6 +747,7 @@ class DeviceVCMembershipForm(forms.ModelForm):
class VCMemberSelectForm(BootstrapMixin, forms.Form):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
query_params={
'virtual_chassis_id': 'null',
@@ -728,6 +770,7 @@ class VCMemberSelectForm(BootstrapMixin, forms.Form):
class ComponentTemplateForm(BootstrapMixin, forms.ModelForm):
device_type = DynamicModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all()
)
@@ -741,10 +784,12 @@ class ComponentTemplateForm(BootstrapMixin, forms.ModelForm):
class ModularComponentTemplateForm(ComponentTemplateForm):
device_type = DynamicModelChoiceField(
+ label=_('Device type'),
queryset=DeviceType.objects.all().all(),
required=False
)
module_type = DynamicModelChoiceField(
+ label=_('Module type'),
queryset=ModuleType.objects.all(),
required=False
)
@@ -797,6 +842,7 @@ class PowerPortTemplateForm(ModularComponentTemplateForm):
class PowerOutletTemplateForm(ModularComponentTemplateForm):
power_port = DynamicModelChoiceField(
+ label=_('Power port'),
queryset=PowerPortTemplate.objects.all(),
required=False,
query_params={
@@ -817,6 +863,7 @@ class PowerOutletTemplateForm(ModularComponentTemplateForm):
class InterfaceTemplateForm(ModularComponentTemplateForm):
bridge = DynamicModelChoiceField(
+ label=_('Bridge'),
queryset=InterfaceTemplate.objects.all(),
required=False,
query_params={
@@ -827,8 +874,8 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
fieldsets = (
(None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge')),
- ('PoE', ('poe_mode', 'poe_type')),
- ('Wireless', ('rf_role',))
+ (_('PoE'), ('poe_mode', 'poe_type')),
+ (_('Wireless'), ('rf_role',)),
)
class Meta:
@@ -840,6 +887,7 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
class FrontPortTemplateForm(ModularComponentTemplateForm):
rear_port = DynamicModelChoiceField(
+ label=_('Rear port'),
queryset=RearPortTemplate.objects.all(),
required=False,
query_params={
@@ -901,6 +949,7 @@ class DeviceBayTemplateForm(ComponentTemplateForm):
class InventoryItemTemplateForm(ComponentTemplateForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=InventoryItemTemplate.objects.all(),
required=False,
query_params={
@@ -908,10 +957,12 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
}
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
required=False
)
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
@@ -947,6 +998,7 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
class DeviceComponentForm(NetBoxModelForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
selector=True
)
@@ -961,6 +1013,7 @@ class DeviceComponentForm(NetBoxModelForm):
class ModularDeviceComponentForm(DeviceComponentForm):
module = DynamicModelChoiceField(
+ label=_('Module'),
queryset=Module.objects.all(),
required=False,
query_params={
@@ -1017,6 +1070,7 @@ class PowerPortForm(ModularDeviceComponentForm):
class PowerOutletForm(ModularDeviceComponentForm):
power_port = DynamicModelChoiceField(
+ label=_('Power port'),
queryset=PowerPort.objects.all(),
required=False,
query_params={
@@ -1043,7 +1097,7 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
vdcs = DynamicModelMultipleChoiceField(
queryset=VirtualDeviceContext.objects.all(),
required=False,
- label='Virtual Device Contexts',
+ label=_('Virtual device contexts'),
query_params={
'device_id': '$device',
}
@@ -1121,13 +1175,13 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
)
fieldsets = (
- ('Interface', ('device', 'module', 'name', 'label', 'type', 'speed', 'duplex', 'description', 'tags')),
- ('Addressing', ('vrf', 'mac_address', 'wwn')),
- ('Operation', ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
- ('Related Interfaces', ('parent', 'bridge', 'lag')),
- ('PoE', ('poe_mode', 'poe_type')),
- ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
- ('Wireless', (
+ (_('Interface'), ('device', 'module', 'name', 'label', 'type', 'speed', 'duplex', 'description', 'tags')),
+ (_('Addressing'), ('vrf', 'mac_address', 'wwn')),
+ (_('Operation'), ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
+ (_('Related Interfaces'), ('parent', 'bridge', 'lag')),
+ (_('PoE'), ('poe_mode', 'poe_type')),
+ (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
+ (_('Wireless'), (
'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'wireless_lan_group', 'wireless_lans',
)),
)
@@ -1233,6 +1287,7 @@ class PopulateDeviceBayForm(BootstrapMixin, forms.Form):
class InventoryItemForm(DeviceComponentForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=InventoryItem.objects.all(),
required=False,
query_params={
@@ -1240,10 +1295,12 @@ class InventoryItemForm(DeviceComponentForm):
}
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
required=False
)
manufacturer = DynamicModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
required=False
)
@@ -1307,8 +1364,8 @@ class InventoryItemForm(DeviceComponentForm):
)
fieldsets = (
- ('Inventory Item', ('device', 'parent', 'name', 'label', 'role', 'description', 'tags')),
- ('Hardware', ('manufacturer', 'part_id', 'serial', 'asset_tag')),
+ (_('Inventory Item'), ('device', 'parent', 'name', 'label', 'role', 'description', 'tags')),
+ (_('Hardware'), ('manufacturer', 'part_id', 'serial', 'asset_tag')),
)
class Meta:
@@ -1359,7 +1416,7 @@ class InventoryItemForm(DeviceComponentForm):
) if self.cleaned_data[field]
]
if len(selected_objects) > 1:
- raise forms.ValidationError("An InventoryItem can only be assigned to a single component.")
+ 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:
@@ -1373,7 +1430,7 @@ class InventoryItemRoleForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Inventory Item Role', (
+ (_('Inventory Item Role'), (
'name', 'slug', 'color', 'description', 'tags',
)),
)
@@ -1387,12 +1444,13 @@ class InventoryItemRoleForm(NetBoxModelForm):
class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
selector=True
)
primary_ip4 = DynamicModelChoiceField(
queryset=IPAddress.objects.all(),
- label='Primary IPv4',
+ label=_('Primary IPv4'),
required=False,
query_params={
'device_id': '$device',
@@ -1401,7 +1459,7 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
)
primary_ip6 = DynamicModelChoiceField(
queryset=IPAddress.objects.all(),
- label='Primary IPv6',
+ label=_('Primary IPv6'),
required=False,
query_params={
'device_id': '$device',
@@ -1410,8 +1468,8 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
)
fieldsets = (
- ('Virtual Device Context', ('device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant'))
+ (_('Virtual Device Context'), ('device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant'))
)
class Meta:
diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py
index 9589ab533..b41e63b58 100644
--- a/netbox/dcim/forms/object_create.py
+++ b/netbox/dcim/forms/object_create.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import *
from netbox.forms import NetBoxModelForm
@@ -38,8 +38,11 @@ class ComponentCreateForm(forms.Form):
Subclass this form when facilitating the creation of one or more component or component template objects based on
a name pattern.
"""
- name = ExpandableNameField()
+ name = ExpandableNameField(
+ label=_('Name'),
+ )
label = ExpandableNameField(
+ label=_('Label'),
required=False,
help_text=_('Alphanumeric ranges are supported. (Must match the number of objects being created.)')
)
@@ -57,8 +60,9 @@ class ComponentCreateForm(forms.Form):
value_count = len(self.cleaned_data[field_name])
if self.cleaned_data[field_name] and value_count != pattern_count:
raise forms.ValidationError({
- field_name: f'The provided pattern specifies {value_count} values, but {pattern_count} are '
- f'expected.'
+ field_name: _(
+ "The provided pattern specifies {value_count} values, but {pattern_count} are expected."
+ ).format(value_count=value_count, pattern_count=pattern_count)
}, code='label_pattern_mismatch')
@@ -222,12 +226,14 @@ class InterfaceCreateForm(ComponentCreateForm, model_forms.InterfaceForm):
super().__init__(*args, **kwargs)
if 'module' in self.fields:
- self.fields['name'].help_text += ' The string {module}
will be replaced with the position ' \
- 'of the assigned module, if any'
+ self.fields['name'].help_text += _(
+ "The string {module}
will be replaced with the position of the assigned module, if any."
+ )
class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
selector=True,
widget=APISelect(
@@ -329,6 +335,7 @@ class InventoryItemCreateForm(ComponentCreateForm, model_forms.InventoryItemForm
class VirtualChassisCreateForm(NetBoxModelForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
initial_params={
@@ -336,6 +343,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
}
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False,
initial_params={
@@ -343,6 +351,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
}
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -351,6 +360,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
}
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
null_option='None',
@@ -359,6 +369,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
}
)
members = DynamicModelMultipleChoiceField(
+ label=_('Members'),
queryset=Device.objects.all(),
required=False,
query_params={
@@ -367,6 +378,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
}
)
initial_position = forms.IntegerField(
+ label=_('Initial position'),
initial=1,
required=False,
help_text=_('Position of the first member device. Increases by one for each additional member.')
@@ -383,7 +395,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
if self.cleaned_data['members'] and self.cleaned_data['initial_position'] is None:
raise forms.ValidationError({
- 'initial_position': "A position must be specified for the first VC member."
+ 'initial_position': _("A position must be specified for the first VC member.")
})
def save(self, *args, **kwargs):
diff --git a/netbox/dcim/forms/object_import.py b/netbox/dcim/forms/object_import.py
index 01efbe123..bab8876da 100644
--- a/netbox/dcim/forms/object_import.py
+++ b/netbox/dcim/forms/object_import.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import InterfacePoEModeChoices, InterfacePoETypeChoices, InterfaceTypeChoices, PortTypeChoices
from dcim.models import *
@@ -57,6 +57,7 @@ class PowerPortTemplateImportForm(ComponentTemplateImportForm):
class PowerOutletTemplateImportForm(ComponentTemplateImportForm):
power_port = forms.ModelChoiceField(
+ label=_('Power port'),
queryset=PowerPortTemplate.objects.all(),
to_field_name='name',
required=False
@@ -85,6 +86,7 @@ class PowerOutletTemplateImportForm(ComponentTemplateImportForm):
class InterfaceTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=InterfaceTypeChoices.CHOICES
)
poe_mode = forms.ChoiceField(
@@ -113,9 +115,11 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm):
class FrontPortTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=PortTypeChoices.CHOICES
)
rear_port = forms.ModelChoiceField(
+ label=_('Rear port'),
queryset=RearPortTemplate.objects.all(),
to_field_name='name'
)
@@ -143,6 +147,7 @@ class FrontPortTemplateImportForm(ComponentTemplateImportForm):
class RearPortTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=PortTypeChoices.CHOICES
)
@@ -173,15 +178,18 @@ class DeviceBayTemplateImportForm(ComponentTemplateImportForm):
class InventoryItemTemplateImportForm(ComponentTemplateImportForm):
parent = forms.ModelChoiceField(
+ label=_('Parent'),
queryset=InventoryItemTemplate.objects.all(),
required=False
)
role = forms.ModelChoiceField(
+ label=_('Role'),
queryset=InventoryItemRole.objects.all(),
to_field_name='name',
required=False
)
manufacturer = forms.ModelChoiceField(
+ label=_('Manufacturer'),
queryset=Manufacturer.objects.all(),
to_field_name='name',
required=False
diff --git a/netbox/extras/forms/bulk_edit.py b/netbox/extras/forms/bulk_edit.py
index 2a55d87da..46bd4d64c 100644
--- a/netbox/extras/forms/bulk_edit.py
+++ b/netbox/extras/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.choices import *
from extras.models import *
@@ -27,16 +27,20 @@ class CustomFieldBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
group_name = forms.CharField(
+ label=_('Group name'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
required=False
)
required = forms.NullBooleanField(
+ label=_('Required'),
required=False,
widget=BulkEditNullBooleanSelect()
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
choice_set = DynamicModelChoiceField(
@@ -50,6 +54,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
initial=''
)
is_cloneable = forms.NullBooleanField(
+ label=_('Is cloneable'),
required=False,
widget=BulkEditNullBooleanSelect()
)
@@ -83,17 +88,21 @@ class CustomLinkBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect()
)
new_window = forms.NullBooleanField(
+ label=_('New window'),
required=False,
widget=BulkEditNullBooleanSelect()
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
button_class = forms.ChoiceField(
+ label=_('Button class'),
choices=add_blank_choice(CustomLinkButtonClassChoices),
required=False
)
@@ -105,18 +114,22 @@ class ExportTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
mime_type = forms.CharField(
+ label=_('MIME type'),
max_length=50,
required=False
)
file_extension = forms.CharField(
+ label=_('File extension'),
max_length=15,
required=False
)
as_attachment = forms.NullBooleanField(
+ label=_('As attachment'),
required=False,
widget=BulkEditNullBooleanSelect()
)
@@ -130,17 +143,21 @@ class SavedFilterBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect()
)
shared = forms.NullBooleanField(
+ label=_('Shared'),
required=False,
widget=BulkEditNullBooleanSelect()
)
@@ -154,26 +171,32 @@ class WebhookBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect()
)
type_create = forms.NullBooleanField(
+ label=_('On create'),
required=False,
widget=BulkEditNullBooleanSelect()
)
type_update = forms.NullBooleanField(
+ label=_('On update'),
required=False,
widget=BulkEditNullBooleanSelect()
)
type_delete = forms.NullBooleanField(
+ label=_('On delete'),
required=False,
widget=BulkEditNullBooleanSelect()
)
type_job_start = forms.NullBooleanField(
+ label=_('On job start'),
required=False,
widget=BulkEditNullBooleanSelect()
)
type_job_end = forms.NullBooleanField(
+ label=_('On job end'),
required=False,
widget=BulkEditNullBooleanSelect()
)
@@ -192,6 +215,7 @@ class WebhookBulkEditForm(BulkEditForm):
label=_('SSL verification')
)
secret = forms.CharField(
+ label=_('Secret'),
required=False
)
ca_file_path = forms.CharField(
@@ -208,9 +232,11 @@ class TagBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
color = ColorField(
+ label=_('Color'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -224,14 +250,17 @@ class ConfigContextBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False,
min_value=0
)
is_active = forms.NullBooleanField(
+ label=_('Is active'),
required=False,
widget=BulkEditNullBooleanSelect()
)
description = forms.CharField(
+ label=_('Description'),
required=False,
max_length=100
)
@@ -245,6 +274,7 @@ class ConfigTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -258,10 +288,12 @@ class JournalEntryBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput
)
kind = forms.ChoiceField(
+ label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices),
required=False
)
comments = forms.CharField(
+ label=_('Comments'),
required=False,
widget=forms.Textarea()
)
diff --git a/netbox/extras/forms/bulk_import.py b/netbox/extras/forms/bulk_import.py
index e91ce7e93..31afbd39d 100644
--- a/netbox/extras/forms/bulk_import.py
+++ b/netbox/extras/forms/bulk_import.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms import SimpleArrayField
from django.utils.safestring import mark_safe
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.choices import *
from extras.models import *
@@ -28,27 +28,32 @@ __all__ = (
class CustomFieldImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'),
help_text=_("One or more assigned object types")
)
type = CSVChoiceField(
+ label=_('Type'),
choices=CustomFieldTypeChoices,
help_text=_('Field data type (e.g. text, integer, etc.)')
)
object_type = CSVContentTypeField(
+ label=_('Object type'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'),
required=False,
help_text=_("Object type (for object or multi-object fields)")
)
choice_set = CSVModelChoiceField(
+ label=_('Choice set'),
queryset=CustomFieldChoiceSet.objects.all(),
to_field_name='name',
required=False,
help_text=_('Choice set (for selection fields)')
)
ui_visibility = CSVChoiceField(
+ label=_('UI visibility'),
choices=CustomFieldVisibilityChoices,
help_text=_('How the custom field is displayed in the user interface')
)
@@ -83,6 +88,7 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
class CustomLinkImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links'),
help_text=_("One or more assigned object types")
@@ -98,6 +104,7 @@ class CustomLinkImportForm(CSVModelForm):
class ExportTemplateImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('export_templates'),
help_text=_("One or more assigned object types")
@@ -121,6 +128,7 @@ class ConfigTemplateImportForm(CSVModelForm):
class SavedFilterImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
help_text=_("One or more assigned object types")
)
@@ -134,6 +142,7 @@ class SavedFilterImportForm(CSVModelForm):
class WebhookImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks'),
help_text=_("One or more assigned object types")
@@ -165,6 +174,7 @@ class JournalEntryImportForm(NetBoxModelImportForm):
label=_('Assigned object type'),
)
kind = CSVChoiceField(
+ label=_('Kind'),
choices=JournalEntryKindChoices,
help_text=_('The classification of entry')
)
diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py
index a181e9a18..5d1d2015e 100644
--- a/netbox/extras/forms/filtersets.py
+++ b/netbox/extras/forms/filtersets.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from core.models import DataFile, DataSource
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
@@ -39,7 +39,7 @@ __all__ = (
class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Attributes', (
+ (_('Attributes'), (
'type', 'content_type_id', 'group_name', 'weight', 'required', 'choice_set_id', 'ui_visibility',
'is_cloneable',
)),
@@ -55,12 +55,15 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
label=_('Field type')
)
group_name = forms.CharField(
+ label=_('Group name'),
required=False
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
required = forms.NullBooleanField(
+ label=_('Required'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -77,6 +80,7 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
label=_('UI visibility')
)
is_cloneable = forms.NullBooleanField(
+ label=_('Is cloneable'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -104,22 +108,26 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
(_('Attributes'), ('content_types', 'enabled', 'new_window', 'weight')),
)
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('custom_links').get_query()),
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
new_window = forms.NullBooleanField(
+ label=_('New window'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
@@ -127,8 +135,8 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Data', ('data_source_id', 'data_file_id')),
- ('Attributes', ('content_types', 'mime_type', 'file_extension', 'as_attachment')),
+ (_('Data'), ('data_source_id', 'data_file_id')),
+ (_('Attributes'), ('content_types', 'mime_type', 'file_extension', 'as_attachment')),
)
data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(),
@@ -144,6 +152,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
}
)
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()),
required=False
)
@@ -152,9 +161,11 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
label=_('MIME type')
)
file_extension = forms.CharField(
+ label=_('File extension'),
required=False
)
as_attachment = forms.NullBooleanField(
+ label=_('As attachment'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -165,13 +176,15 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Attributes', ('content_type_id', 'name',)),
+ (_('Attributes'), ('content_type_id', 'name',)),
)
content_type_id = ContentTypeChoiceField(
+ label=_('Content type'),
queryset=ContentType.objects.filter(FeatureQuery('custom_fields').get_query()),
required=False
)
name = forms.CharField(
+ label=_('Name'),
required=False
)
@@ -179,25 +192,29 @@ class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm):
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Attributes', ('content_types', 'enabled', 'shared', 'weight')),
+ (_('Attributes'), ('content_types', 'enabled', 'shared', 'weight')),
)
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()),
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
shared = forms.NullBooleanField(
+ label=_('Shared'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
)
)
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
@@ -205,8 +222,8 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
class WebhookFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id')),
- ('Attributes', ('content_type_id', 'http_method', 'enabled')),
- ('Events', ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
+ (_('Attributes'), ('content_type_id', 'http_method', 'enabled')),
+ (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
)
content_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.filter(FeatureQuery('webhooks').get_query()),
@@ -219,6 +236,7 @@ class WebhookFilterForm(SavedFiltersMixin, FilterForm):
label=_('HTTP method')
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -278,11 +296,11 @@ class TagFilterForm(SavedFiltersMixin, FilterForm):
class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id', 'tag_id')),
- ('Data', ('data_source_id', 'data_file_id')),
- ('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')),
- ('Device', ('device_type_id', 'platform_id', 'role_id')),
- ('Cluster', ('cluster_type_id', 'cluster_group_id', 'cluster_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id'))
+ (_('Data'), ('data_source_id', 'data_file_id')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
+ (_('Device'), ('device_type_id', 'platform_id', 'role_id')),
+ (_('Cluster'), ('cluster_type_id', 'cluster_group_id', 'cluster_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id'))
)
data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(),
@@ -368,7 +386,7 @@ class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Data', ('data_source_id', 'data_file_id')),
+ (_('Data'), ('data_source_id', 'data_file_id')),
)
data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(),
@@ -400,8 +418,8 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
model = JournalEntry
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Creation', ('created_before', 'created_after', 'created_by_id')),
- ('Attributes', ('assigned_object_type_id', 'kind'))
+ (_('Creation'), ('created_before', 'created_after', 'created_by_id')),
+ (_('Attributes'), ('assigned_object_type_id', 'kind'))
)
created_after = forms.DateTimeField(
required=False,
@@ -430,6 +448,7 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
)
)
kind = forms.ChoiceField(
+ label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices),
required=False
)
@@ -440,8 +459,8 @@ class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
model = ObjectChange
fieldsets = (
(None, ('q', 'filter_id')),
- ('Time', ('time_before', 'time_after')),
- ('Attributes', ('action', 'user_id', 'changed_object_type_id')),
+ (_('Time'), ('time_before', 'time_after')),
+ (_('Attributes'), ('action', 'user_id', 'changed_object_type_id')),
)
time_after = forms.DateTimeField(
required=False,
@@ -454,6 +473,7 @@ class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
widget=DateTimePicker()
)
action = forms.ChoiceField(
+ label=_('Action'),
choices=add_blank_choice(ObjectChangeActionChoices),
required=False
)
diff --git a/netbox/extras/forms/misc.py b/netbox/extras/forms/misc.py
index b52338e76..0fd1a889d 100644
--- a/netbox/extras/forms/misc.py
+++ b/netbox/extras/forms/misc.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import gettext_lazy as _
__all__ = (
'RenderMarkdownForm',
@@ -10,5 +11,6 @@ class RenderMarkdownForm(forms.Form):
Provides basic validation for markup to be rendered.
"""
text = forms.CharField(
+ label=_('Text'),
required=False
)
diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py
index 35700967c..414563f59 100644
--- a/netbox/extras/forms/model_forms.py
+++ b/netbox/extras/forms/model_forms.py
@@ -4,7 +4,7 @@ from django import forms
from django.conf import settings
from django.db.models import Q
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from core.forms.mixins import SyncedDataMixin
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
@@ -42,10 +42,12 @@ __all__ = (
class CustomFieldForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'),
)
object_type = ContentTypeChoiceField(
+ label=_('Object type'),
queryset=ContentType.objects.all(),
# TODO: Come up with a canonical way to register suitable models
limit_choices_to=FeatureQuery('webhooks').get_query() | Q(app_label='auth', model__in=['user', 'group']),
@@ -58,12 +60,12 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm):
)
fieldsets = (
- ('Custom Field', (
+ (_('Custom Field'), (
'content_types', 'name', 'label', 'group_name', 'type', 'object_type', 'required', 'description',
)),
- ('Behavior', ('search_weight', 'filter_logic', 'ui_visibility', 'weight', 'is_cloneable')),
- ('Values', ('default', 'choice_set')),
- ('Validation', ('validation_minimum', 'validation_maximum', 'validation_regex')),
+ (_('Behavior'), ('search_weight', 'filter_logic', 'ui_visibility', 'weight', 'is_cloneable')),
+ (_('Values'), ('default', 'choice_set')),
+ (_('Validation'), ('validation_minimum', 'validation_maximum', 'validation_regex')),
)
class Meta:
@@ -106,13 +108,14 @@ class CustomFieldChoiceSetForm(BootstrapMixin, forms.ModelForm):
class CustomLinkForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links')
)
fieldsets = (
- ('Custom Link', ('name', 'content_types', 'weight', 'group_name', 'button_class', 'enabled', 'new_window')),
- ('Templates', ('link_text', 'link_url')),
+ (_('Custom Link'), ('name', 'content_types', 'weight', 'group_name', 'button_class', 'enabled', 'new_window')),
+ (_('Templates'), ('link_text', 'link_url')),
)
class Meta:
@@ -133,18 +136,20 @@ class CustomLinkForm(BootstrapMixin, forms.ModelForm):
class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('export_templates')
)
template_code = forms.CharField(
+ label=_('Template code'),
required=False,
widget=forms.Textarea(attrs={'class': 'font-monospace'})
)
fieldsets = (
- ('Export Template', ('name', 'content_types', 'description', 'template_code')),
- ('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')),
- ('Rendering', ('mime_type', 'file_extension', 'as_attachment')),
+ (_('Export Template'), ('name', 'content_types', 'description', 'template_code')),
+ (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
+ (_('Rendering'), ('mime_type', 'file_extension', 'as_attachment')),
)
class Meta:
@@ -165,7 +170,7 @@ class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean()
if not self.cleaned_data.get('template_code') and not self.cleaned_data.get('data_file'):
- raise forms.ValidationError("Must specify either local content or a data file")
+ raise forms.ValidationError(_("Must specify either local content or a data file"))
return self.cleaned_data
@@ -173,13 +178,14 @@ class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
class SavedFilterForm(BootstrapMixin, forms.ModelForm):
slug = SlugField()
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.all()
)
parameters = JSONField()
fieldsets = (
- ('Saved Filter', ('name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared')),
- ('Parameters', ('parameters',)),
+ (_('Saved Filter'), ('name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared')),
+ (_('Parameters'), ('parameters',)),
)
class Meta:
@@ -198,6 +204,7 @@ class SavedFilterForm(BootstrapMixin, forms.ModelForm):
class BookmarkForm(BootstrapMixin, forms.ModelForm):
object_type = ContentTypeChoiceField(
+ label=_('Object type'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('bookmarks').get_query()
)
@@ -209,29 +216,30 @@ class BookmarkForm(BootstrapMixin, forms.ModelForm):
class WebhookForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField(
+ label=_('Content types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks')
)
fieldsets = (
- ('Webhook', ('name', 'content_types', 'enabled')),
- ('Events', ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
- ('HTTP Request', (
+ (_('Webhook'), ('name', 'content_types', 'enabled')),
+ (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
+ (_('HTTP Request'), (
'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret',
)),
- ('Conditions', ('conditions',)),
- ('SSL', ('ssl_verification', 'ca_file_path')),
+ (_('Conditions'), ('conditions',)),
+ (_('SSL'), ('ssl_verification', 'ca_file_path')),
)
class Meta:
model = Webhook
fields = '__all__'
labels = {
- 'type_create': 'Creations',
- 'type_update': 'Updates',
- 'type_delete': 'Deletions',
- 'type_job_start': 'Job executions',
- 'type_job_end': 'Job terminations',
+ 'type_create': _('Creations'),
+ 'type_update': _('Updates'),
+ 'type_delete': _('Deletions'),
+ 'type_job_start': _('Job executions'),
+ 'type_job_end': _('Job terminations'),
}
widgets = {
'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}),
@@ -243,6 +251,7 @@ class WebhookForm(BootstrapMixin, forms.ModelForm):
class TagForm(BootstrapMixin, forms.ModelForm):
slug = SlugField()
object_types = ContentTypeMultipleChoiceField(
+ label=_('Object types'),
queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('tags'),
required=False
@@ -261,65 +270,79 @@ class TagForm(BootstrapMixin, forms.ModelForm):
class ConfigContextForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
regions = DynamicModelMultipleChoiceField(
+ label=_('Regions'),
queryset=Region.objects.all(),
required=False
)
site_groups = DynamicModelMultipleChoiceField(
+ label=_('Site groups'),
queryset=SiteGroup.objects.all(),
required=False
)
sites = DynamicModelMultipleChoiceField(
+ label=_('Sites'),
queryset=Site.objects.all(),
required=False
)
locations = DynamicModelMultipleChoiceField(
+ label=_('Locations'),
queryset=Location.objects.all(),
required=False
)
device_types = DynamicModelMultipleChoiceField(
+ label=_('Device types'),
queryset=DeviceType.objects.all(),
required=False
)
roles = DynamicModelMultipleChoiceField(
+ label=_('Roles'),
queryset=DeviceRole.objects.all(),
required=False
)
platforms = DynamicModelMultipleChoiceField(
+ label=_('Platforms'),
queryset=Platform.objects.all(),
required=False
)
cluster_types = DynamicModelMultipleChoiceField(
+ label=_('Cluster types'),
queryset=ClusterType.objects.all(),
required=False
)
cluster_groups = DynamicModelMultipleChoiceField(
+ label=_('Cluster groups'),
queryset=ClusterGroup.objects.all(),
required=False
)
clusters = DynamicModelMultipleChoiceField(
+ label=_('Clusters'),
queryset=Cluster.objects.all(),
required=False
)
tenant_groups = DynamicModelMultipleChoiceField(
+ label=_('Tenat groups'),
queryset=TenantGroup.objects.all(),
required=False
)
tenants = DynamicModelMultipleChoiceField(
+ label=_('Tenants'),
queryset=Tenant.objects.all(),
required=False
)
tags = DynamicModelMultipleChoiceField(
+ label=_('Tags'),
queryset=Tag.objects.all(),
required=False
)
data = JSONField(
+ label=_('Data'),
required=False
)
fieldsets = (
- ('Config Context', ('name', 'weight', 'description', 'data', 'is_active')),
- ('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')),
- ('Assignment', (
+ (_('Config Context'), ('name', 'weight', 'description', 'data', 'is_active')),
+ (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
+ (_('Assignment'), (
'regions', 'site_groups', 'sites', 'locations', 'device_types', 'roles', 'platforms', 'cluster_types',
'cluster_groups', 'clusters', 'tenant_groups', 'tenants', 'tags',
)),
@@ -351,25 +374,27 @@ class ConfigContextForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean()
if not self.cleaned_data.get('data') and not self.cleaned_data.get('data_file'):
- raise forms.ValidationError("Must specify either local data or a data file")
+ raise forms.ValidationError(_("Must specify either local data or a data file"))
return self.cleaned_data
class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
tags = DynamicModelMultipleChoiceField(
+ label=_('Tags'),
queryset=Tag.objects.all(),
required=False
)
template_code = forms.CharField(
+ label=_('Template code'),
required=False,
widget=forms.Textarea(attrs={'class': 'font-monospace'})
)
fieldsets = (
- ('Config Template', ('name', 'description', 'environment_params', 'tags')),
- ('Content', ('template_code',)),
- ('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')),
+ (_('Config Template'), ('name', 'description', 'environment_params', 'tags')),
+ (_('Content'), ('template_code',)),
+ (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
)
class Meta:
@@ -393,7 +418,7 @@ class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean()
if not self.cleaned_data.get('template_code') and not self.cleaned_data.get('data_file'):
- raise forms.ValidationError("Must specify either local content or a data file")
+ raise forms.ValidationError(_("Must specify either local content or a data file"))
return self.cleaned_data
@@ -409,6 +434,7 @@ class ImageAttachmentForm(BootstrapMixin, forms.ModelForm):
class JournalEntryForm(NetBoxModelForm):
kind = forms.ChoiceField(
+ label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices),
required=False
)
@@ -451,16 +477,16 @@ class ConfigRevisionForm(BootstrapMixin, forms.ModelForm, metaclass=ConfigFormMe
"""
fieldsets = (
- ('Rack Elevations', ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH')),
- ('Power', ('POWERFEED_DEFAULT_VOLTAGE', 'POWERFEED_DEFAULT_AMPERAGE', 'POWERFEED_DEFAULT_MAX_UTILIZATION')),
- ('IPAM', ('ENFORCE_GLOBAL_UNIQUE', 'PREFER_IPV4')),
- ('Security', ('ALLOWED_URL_SCHEMES',)),
- ('Banners', ('BANNER_LOGIN', 'BANNER_MAINTENANCE', 'BANNER_TOP', 'BANNER_BOTTOM')),
- ('Pagination', ('PAGINATE_COUNT', 'MAX_PAGE_SIZE')),
- ('Validation', ('CUSTOM_VALIDATORS',)),
- ('User Preferences', ('DEFAULT_USER_PREFERENCES',)),
- ('Miscellaneous', ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOB_RETENTION', 'MAPS_URL')),
- ('Config Revision', ('comment',))
+ (_('Rack Elevations'), ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH')),
+ (_('Power'), ('POWERFEED_DEFAULT_VOLTAGE', 'POWERFEED_DEFAULT_AMPERAGE', 'POWERFEED_DEFAULT_MAX_UTILIZATION')),
+ (_('IPAM'), ('ENFORCE_GLOBAL_UNIQUE', 'PREFER_IPV4')),
+ (_('Security'), ('ALLOWED_URL_SCHEMES',)),
+ (_('Banners'), ('BANNER_LOGIN', 'BANNER_MAINTENANCE', 'BANNER_TOP', 'BANNER_BOTTOM')),
+ (_('Pagination'), ('PAGINATE_COUNT', 'MAX_PAGE_SIZE')),
+ (_('Validation'), ('CUSTOM_VALIDATORS',)),
+ (_('User Preferences'), ('DEFAULT_USER_PREFERENCES',)),
+ (_('Miscellaneous'), ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOB_RETENTION', 'MAPS_URL')),
+ (_('Config Revision'), ('comment',))
)
class Meta:
@@ -487,11 +513,11 @@ class ConfigRevisionForm(BootstrapMixin, forms.ModelForm, metaclass=ConfigFormMe
help_text = self.fields[param.name].help_text
if help_text:
help_text += '
' # Line break
- help_text += f'Current value: {value}'
+ help_text += _('Current value: {value}').format(value=value)
if is_static:
- help_text += ' (defined statically)'
+ help_text += _(' (defined statically)')
elif value == param.default:
- help_text += ' (default)'
+ help_text += _(' (default)')
self.fields[param.name].help_text = help_text
self.fields[param.name].initial = value
if is_static:
diff --git a/netbox/extras/forms/reports.py b/netbox/extras/forms/reports.py
index 4000c01e6..0ff7d1509 100644
--- a/netbox/extras/forms/reports.py
+++ b/netbox/extras/forms/reports.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.choices import DurationChoices
from utilities.forms import BootstrapMixin
@@ -33,7 +33,7 @@ class ReportForm(BootstrapMixin, forms.Form):
# Annotate the current system time for reference
now = local_now().strftime('%Y-%m-%d %H:%M:%S')
- self.fields['schedule_at'].help_text += f' (current time: {now})'
+ self.fields['schedule_at'].help_text += _(' (current time: {now})').format(now=now)
# Remove scheduling fields if scheduling is disabled
if not scheduling_enabled:
diff --git a/netbox/extras/forms/scripts.py b/netbox/extras/forms/scripts.py
index 19a7878e1..c555747ae 100644
--- a/netbox/extras/forms/scripts.py
+++ b/netbox/extras/forms/scripts.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.choices import DurationChoices
from utilities.forms import BootstrapMixin
@@ -39,7 +39,7 @@ class ScriptForm(BootstrapMixin, forms.Form):
# Annotate the current system time for reference
now = local_now().strftime('%Y-%m-%d %H:%M:%S')
- self.fields['_schedule_at'].help_text += f' (current time: {now})'
+ self.fields['_schedule_at'].help_text += _(' (current time: {now})').format(now=now)
# Remove scheduling fields if scheduling is disabled
if not scheduling_enabled:
diff --git a/netbox/ipam/forms/bulk_create.py b/netbox/ipam/forms/bulk_create.py
index 1ba786aae..ea553c655 100644
--- a/netbox/ipam/forms/bulk_create.py
+++ b/netbox/ipam/forms/bulk_create.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from utilities.forms import BootstrapMixin
from utilities.forms.fields import ExpandableIPAddressField
diff --git a/netbox/ipam/forms/bulk_edit.py b/netbox/ipam/forms/bulk_edit.py
index 71ce14040..548d01afa 100644
--- a/netbox/ipam/forms/bulk_edit.py
+++ b/netbox/ipam/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Region, Site, SiteGroup
from ipam.choices import *
@@ -37,6 +37,7 @@ __all__ = (
class VRFBulkEditForm(NetBoxModelBulkEditForm):
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
@@ -46,12 +47,11 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
label=_('Enforce unique space')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = VRF
fieldsets = (
@@ -62,16 +62,16 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = RouteTarget
fieldsets = (
@@ -82,10 +82,12 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
class RIRBulkEditForm(NetBoxModelBulkEditForm):
is_private = forms.NullBooleanField(
+ label=_('Is private'),
required=False,
widget=BulkEditNullBooleanSelect
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -104,10 +106,12 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR')
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -121,6 +125,7 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
class ASNBulkEditForm(NetBoxModelBulkEditForm):
sites = DynamicModelMultipleChoiceField(
+ label=_('Sites'),
queryset=Site.objects.all(),
required=False
)
@@ -130,16 +135,16 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR')
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = ASN
fieldsets = (
@@ -155,19 +160,20 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR')
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
date_added = forms.DateField(
+ label=_('Date added'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Aggregate
fieldsets = (
@@ -178,9 +184,11 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
class RoleBulkEditForm(NetBoxModelBulkEditForm):
weight = forms.IntegerField(
+ label=_('Weight'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -194,14 +202,17 @@ class RoleBulkEditForm(NetBoxModelBulkEditForm):
class PrefixBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -215,19 +226,23 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF')
)
prefix_length = forms.IntegerField(
+ label=_('Prefix length'),
min_value=PREFIX_LENGTH_MIN,
max_value=PREFIX_LENGTH_MAX,
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(PrefixStatusChoices),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
@@ -242,18 +257,17 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label=_('Treat as 100% utilized')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Prefix
fieldsets = (
(None, ('tenant', 'status', 'role', 'description')),
- ('Site', ('region', 'site_group', 'site')),
- ('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
+ (_('Site'), ('region', 'site_group', 'site')),
+ (_('Addressing'), ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
)
nullable_fields = (
'site', 'vrf', 'tenant', 'role', 'description', 'comments',
@@ -267,14 +281,17 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF')
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(IPRangeStatusChoices),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
@@ -284,12 +301,11 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('Treat as 100% utilized')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = IPRange
fieldsets = (
@@ -307,19 +323,23 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF')
)
mask_length = forms.IntegerField(
+ label=_('Mask length'),
min_value=IPADDRESS_MASK_LENGTH_MIN,
max_value=IPADDRESS_MASK_LENGTH_MAX,
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(IPAddressStatusChoices),
required=False
)
role = forms.ChoiceField(
+ label=_('Role'),
choices=add_blank_choice(IPAddressRoleChoices),
required=False
)
@@ -329,17 +349,16 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label=_('DNS name')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = IPAddress
fieldsets = (
(None, ('status', 'role', 'tenant', 'description')),
- ('Addressing', ('vrf', 'mask_length', 'dns_name')),
+ (_('Addressing'), ('vrf', 'mask_length', 'dns_name')),
)
nullable_fields = (
'vrf', 'role', 'tenant', 'dns_name', 'description', 'comments',
@@ -348,6 +367,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
protocol = forms.ChoiceField(
+ label=_('Protocol'),
choices=add_blank_choice(FHRPGroupProtocolChoices),
required=False
)
@@ -367,27 +387,28 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
label=_('Authentication key')
)
name = forms.CharField(
+ label=_('Name'),
max_length=100,
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = FHRPGroup
fieldsets = (
(None, ('protocol', 'group_id', 'name', 'description')),
- ('Authentication', ('auth_type', 'auth_key')),
+ (_('Authentication'), ('auth_type', 'auth_key')),
)
nullable_fields = ('auth_type', 'auth_key', 'name', 'description', 'comments')
class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False
)
@@ -404,6 +425,7 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
label=_('Maximum child VLAN VID')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -417,14 +439,17 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
class VLANBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -433,6 +458,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
}
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=VLANGroup.objects.all(),
required=False,
query_params={
@@ -440,29 +466,31 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
}
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(VLANStatusChoices),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = VLAN
fieldsets = (
(None, ('status', 'role', 'tenant', 'description')),
- ('Site & Group', ('region', 'site_group', 'site', 'group')),
+ (_('Site & Group'), ('region', 'site_group', 'site', 'group')),
)
nullable_fields = (
'site', 'group', 'tenant', 'role', 'description', 'comments',
@@ -471,10 +499,12 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
protocol = forms.ChoiceField(
+ label=_('Protocol'),
choices=add_blank_choice(ServiceProtocolChoices),
required=False
)
ports = NumericArrayField(
+ label=_('Ports'),
base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX
@@ -482,12 +512,11 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = ServiceTemplate
fieldsets = (
@@ -502,20 +531,21 @@ class ServiceBulkEditForm(ServiceTemplateBulkEditForm):
class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(L2VPNTypeChoices),
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = L2VPN
fieldsets = (
diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py
index 683d40f49..9b7c624d2 100644
--- a/netbox/ipam/forms/bulk_import.py
+++ b/netbox/ipam/forms/bulk_import.py
@@ -2,7 +2,7 @@ from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.db.models import Q
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Device, Interface, Site
from ipam.choices import *
@@ -36,6 +36,7 @@ __all__ = (
class VRFImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -49,6 +50,7 @@ class VRFImportForm(NetBoxModelImportForm):
class RouteTargetImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -70,11 +72,13 @@ class RIRImportForm(NetBoxModelImportForm):
class AggregateImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField(
+ label=_('RIR'),
queryset=RIR.objects.all(),
to_field_name='name',
help_text=_('Assigned RIR')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -88,11 +92,13 @@ class AggregateImportForm(NetBoxModelImportForm):
class ASNRangeImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField(
+ label=_('RIR'),
queryset=RIR.objects.all(),
to_field_name='name',
help_text=_('Assigned RIR')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -106,11 +112,13 @@ class ASNRangeImportForm(NetBoxModelImportForm):
class ASNImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField(
+ label=_('RIR'),
queryset=RIR.objects.all(),
to_field_name='name',
help_text=_('Assigned RIR')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
@@ -132,40 +140,47 @@ class RoleImportForm(NetBoxModelImportForm):
class PrefixImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField(
+ label=_('VRF'),
queryset=VRF.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned VRF')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned site')
)
vlan_group = CSVModelChoiceField(
+ label=_('VLAN group'),
queryset=VLANGroup.objects.all(),
required=False,
to_field_name='name',
help_text=_("VLAN's group (if any)")
)
vlan = CSVModelChoiceField(
+ label=_('VLAN'),
queryset=VLAN.objects.all(),
required=False,
to_field_name='vid',
help_text=_("Assigned VLAN")
)
status = CSVChoiceField(
+ label=_('Status'),
choices=PrefixStatusChoices,
help_text=_('Operational status')
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False,
to_field_name='name',
@@ -211,22 +226,26 @@ class PrefixImportForm(NetBoxModelImportForm):
class IPRangeImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField(
+ label=_('VRF'),
queryset=VRF.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned VRF')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=IPRangeStatusChoices,
help_text=_('Operational status')
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False,
to_field_name='name',
@@ -243,45 +262,53 @@ class IPRangeImportForm(NetBoxModelImportForm):
class IPAddressImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField(
+ label=_('VRF'),
queryset=VRF.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned VRF')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned tenant')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=IPAddressStatusChoices,
help_text=_('Operational status')
)
role = CSVChoiceField(
+ label=_('Role'),
choices=IPAddressRoleChoices,
required=False,
help_text=_('Functional role')
)
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent device of assigned interface (if any)')
)
virtual_machine = CSVModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent VM of assigned interface (if any)')
)
interface = CSVModelChoiceField(
+ label=_('Interface'),
queryset=Interface.objects.none(), # Can also refer to VMInterface
required=False,
to_field_name='name',
help_text=_('Assigned interface')
)
is_primary = forms.BooleanField(
+ label=_('Is primary'),
help_text=_('Make this the primary IP for the assigned device'),
required=False
)
@@ -321,11 +348,11 @@ class IPAddressImportForm(NetBoxModelImportForm):
# Validate is_primary
if is_primary and not device and not virtual_machine:
raise forms.ValidationError({
- "is_primary": "No device or virtual machine specified; cannot set as primary IP"
+ "is_primary": _("No device or virtual machine specified; cannot set as primary IP")
})
if is_primary and not interface:
raise forms.ValidationError({
- "is_primary": "No interface specified; cannot set as primary IP"
+ "is_primary": _("No interface specified; cannot set as primary IP")
})
def save(self, *args, **kwargs):
@@ -350,9 +377,11 @@ class IPAddressImportForm(NetBoxModelImportForm):
class FHRPGroupImportForm(NetBoxModelImportForm):
protocol = CSVChoiceField(
+ label=_('Protocol'),
choices=FHRPGroupProtocolChoices
)
auth_type = CSVChoiceField(
+ label=_('Auth type'),
choices=FHRPGroupAuthTypeChoices,
required=False
)
@@ -373,13 +402,13 @@ class VLANGroupImportForm(NetBoxModelImportForm):
min_value=VLAN_VID_MIN,
max_value=VLAN_VID_MAX,
required=False,
- label=f'Minimum child VLAN VID (default: {VLAN_VID_MIN})'
+ label=_('Minimum child VLAN VID (default: {minimum})').format(minimum=VLAN_VID_MIN)
)
max_vid = forms.IntegerField(
min_value=VLAN_VID_MIN,
max_value=VLAN_VID_MAX,
required=False,
- label=f'Maximum child VLAN VID (default: {VLAN_VID_MIN})'
+ label=_('Maximum child VLAN VID (default: {maximum})').format(maximum=VLAN_VID_MIN)
)
class Meta:
@@ -392,28 +421,33 @@ class VLANGroupImportForm(NetBoxModelImportForm):
class VLANImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned site')
)
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=VLANGroup.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned VLAN group')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned tenant')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=VLANStatusChoices,
help_text=_('Operational status')
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False,
to_field_name='name',
@@ -427,6 +461,7 @@ class VLANImportForm(NetBoxModelImportForm):
class ServiceTemplateImportForm(NetBoxModelImportForm):
protocol = CSVChoiceField(
+ label=_('Protocol'),
choices=ServiceProtocolChoices,
help_text=_('IP protocol')
)
@@ -438,18 +473,21 @@ class ServiceTemplateImportForm(NetBoxModelImportForm):
class ServiceImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
to_field_name='name',
help_text=_('Required if not assigned to a VM')
)
virtual_machine = CSVModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
required=False,
to_field_name='name',
help_text=_('Required if not assigned to a device')
)
protocol = CSVChoiceField(
+ label=_('Protocol'),
choices=ServiceProtocolChoices,
help_text=_('IP protocol')
)
@@ -461,11 +499,13 @@ class ServiceImportForm(NetBoxModelImportForm):
class L2VPNImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
)
type = CSVChoiceField(
+ label=_('Type'),
choices=L2VPNTypeChoices,
help_text=_('L2VPN type')
)
@@ -484,24 +524,28 @@ class L2VPNTerminationImportForm(NetBoxModelImportForm):
label=_('L2VPN'),
)
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent device (for interface)')
)
virtual_machine = CSVModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent virtual machine (for interface)')
)
interface = CSVModelChoiceField(
+ label=_('Interface'),
queryset=Interface.objects.none(), # Can also refer to VMInterface
required=False,
to_field_name='name',
help_text=_('Assigned interface (device or VM)')
)
vlan = CSVModelChoiceField(
+ label=_('VLAN'),
queryset=VLAN.objects.all(),
required=False,
to_field_name='name',
@@ -531,10 +575,10 @@ class L2VPNTerminationImportForm(NetBoxModelImportForm):
super().clean()
if self.cleaned_data.get('device') and self.cleaned_data.get('virtual_machine'):
- raise ValidationError('Cannot import device and VM interface terminations simultaneously.')
+ raise ValidationError(_('Cannot import device and VM interface terminations simultaneously.'))
if not (self.cleaned_data.get('interface') or self.cleaned_data.get('vlan')):
- raise ValidationError('Each termination must specify either an interface or a VLAN.')
+ raise ValidationError(_('Each termination must specify either an interface or a VLAN.'))
if self.cleaned_data.get('interface') and self.cleaned_data.get('vlan'):
- raise ValidationError('Cannot assign both an interface and a VLAN.')
+ raise ValidationError(_('Cannot assign both an interface and a VLAN.'))
self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vlan')
diff --git a/netbox/ipam/forms/filtersets.py b/netbox/ipam/forms/filtersets.py
index 53fecfe2f..299d70565 100644
--- a/netbox/ipam/forms/filtersets.py
+++ b/netbox/ipam/forms/filtersets.py
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Location, Rack, Region, Site, SiteGroup, Device
from ipam.choices import *
@@ -47,8 +47,8 @@ class VRFFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VRF
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Route Targets', ('import_target_id', 'export_target_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Route Targets'), ('import_target_id', 'export_target_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
import_target_id = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(),
@@ -67,8 +67,8 @@ class RouteTargetFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = RouteTarget
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('VRF', ('importing_vrf_id', 'exporting_vrf_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('VRF'), ('importing_vrf_id', 'exporting_vrf_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
importing_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
@@ -99,8 +99,8 @@ class AggregateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Aggregate
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('family', 'rir_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Attributes'), ('family', 'rir_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
family = forms.ChoiceField(
required=False,
@@ -119,8 +119,8 @@ class ASNRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = ASNRange
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Range', ('rir_id', 'start', 'end')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Range'), ('rir_id', 'start', 'end')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(),
@@ -128,9 +128,11 @@ class ASNRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('RIR')
)
start = forms.IntegerField(
+ label=_('Start'),
required=False
)
end = forms.IntegerField(
+ label=_('End'),
required=False
)
tag = TagFilterField(model)
@@ -140,8 +142,8 @@ class ASNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = ASN
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Assignment', ('rir_id', 'site_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Assignment'), ('rir_id', 'site_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(),
@@ -165,10 +167,10 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Prefix
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Addressing', ('within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized')),
- ('VRF', ('vrf_id', 'present_in_vrf_id')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Addressing'), ('within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized')),
+ (_('VRF'), ('vrf_id', 'present_in_vrf_id')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
mask_length__lte = forms.IntegerField(
widget=forms.HiddenInput()
@@ -204,6 +206,7 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Present in VRF')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=PrefixStatusChoices,
required=False
)
@@ -253,8 +256,8 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPRange
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attriubtes', ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Attriubtes'), ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
family = forms.ChoiceField(
required=False,
@@ -268,6 +271,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
null_option='Global'
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=IPRangeStatusChoices,
required=False
)
@@ -291,10 +295,10 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPAddress
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface')),
- ('VRF', ('vrf_id', 'present_in_vrf_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Device/VM', ('device_id', 'virtual_machine_id')),
+ (_('Attributes'), ('parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface')),
+ (_('VRF'), ('vrf_id', 'present_in_vrf_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Device/VM'), ('device_id', 'virtual_machine_id')),
)
parent = forms.CharField(
required=False,
@@ -337,10 +341,12 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Assigned VM'),
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=IPAddressStatusChoices,
required=False
)
role = forms.MultipleChoiceField(
+ label=_('Role'),
choices=IPAddressRoleChoices,
required=False
)
@@ -358,29 +364,31 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
model = FHRPGroup
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('name', 'protocol', 'group_id')),
- ('Authentication', ('auth_type', 'auth_key')),
+ (_('Attributes'), ('name', 'protocol', 'group_id')),
+ (_('Authentication'), ('auth_type', 'auth_key')),
)
name = forms.CharField(
+ label=_('Name'),
required=False
)
protocol = forms.MultipleChoiceField(
+ label=_('Protocol'),
choices=FHRPGroupProtocolChoices,
required=False
)
group_id = forms.IntegerField(
min_value=0,
required=False,
- label='Group ID'
+ label=_('Group ID')
)
auth_type = forms.MultipleChoiceField(
choices=FHRPGroupAuthTypeChoices,
required=False,
- label='Authentication type'
+ label=_('Authentication type')
)
auth_key = forms.CharField(
required=False,
- label='Authentication key'
+ label=_('Authentication key')
)
tag = TagFilterField(model)
@@ -388,8 +396,8 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
class VLANGroupFilterForm(NetBoxModelFilterSetForm):
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region', 'sitegroup', 'site', 'location', 'rack')),
- ('VLAN ID', ('min_vid', 'max_vid')),
+ (_('Location'), ('region', 'sitegroup', 'site', 'location', 'rack')),
+ (_('VLAN ID'), ('min_vid', 'max_vid')),
)
model = VLANGroup
region = DynamicModelMultipleChoiceField(
@@ -436,9 +444,9 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VLAN
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Attributes', ('group_id', 'status', 'role_id', 'vid', 'l2vpn_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Attributes'), ('group_id', 'status', 'role_id', 'vid', 'l2vpn_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@@ -469,6 +477,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('VLAN group')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=VLANStatusChoices,
required=False
)
@@ -480,7 +489,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
)
vid = forms.IntegerField(
required=False,
- label='VLAN ID'
+ label=_('VLAN ID')
)
l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(),
@@ -494,13 +503,15 @@ class ServiceTemplateFilterForm(NetBoxModelFilterSetForm):
model = ServiceTemplate
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('protocol', 'port')),
+ (_('Attributes'), ('protocol', 'port')),
)
protocol = forms.ChoiceField(
+ label=_('Protocol'),
choices=add_blank_choice(ServiceProtocolChoices),
required=False
)
port = forms.IntegerField(
+ label=_('Port'),
required=False,
)
tag = TagFilterField(model)
@@ -515,10 +526,11 @@ class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = L2VPN
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('type', 'import_target_id', 'export_target_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
+ (_('Attributes'), ('type', 'import_target_id', 'export_target_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
)
type = forms.ChoiceField(
+ label=_('Type'),
choices=add_blank_choice(L2VPNTypeChoices),
required=False
)
@@ -539,14 +551,14 @@ class L2VPNTerminationFilterForm(NetBoxModelFilterSetForm):
model = L2VPNTermination
fieldsets = (
(None, ('filter_id', 'l2vpn_id',)),
- ('Assigned Object', (
+ (_('Assigned Object'), (
'assigned_object_type_id', 'region_id', 'site_id', 'device_id', 'virtual_machine_id', 'vlan_id',
)),
)
l2vpn_id = DynamicModelChoiceField(
queryset=L2VPN.objects.all(),
required=False,
- label='L2VPN'
+ label=_('L2VPN')
)
assigned_object_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.filter(L2VPN_ASSIGNMENT_MODELS),
diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py
index a3c218fc9..c466e279f 100644
--- a/netbox/ipam/forms/model_forms.py
+++ b/netbox/ipam/forms/model_forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Device, Interface, Location, Rack, Region, Site, SiteGroup
from ipam.choices import *
@@ -46,19 +46,21 @@ __all__ = (
class VRFForm(TenancyForm, NetBoxModelForm):
import_targets = DynamicModelMultipleChoiceField(
+ label=_('Import targets'),
queryset=RouteTarget.objects.all(),
required=False
)
export_targets = DynamicModelMultipleChoiceField(
+ label=_('Export targets'),
queryset=RouteTarget.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')),
- ('Route Targets', ('import_targets', 'export_targets')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('VRF'), ('name', 'rd', 'enforce_unique', 'description', 'tags')),
+ (_('Route Targets'), ('import_targets', 'export_targets')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -90,7 +92,7 @@ class RIRForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('RIR', (
+ (_('RIR'), (
'name', 'slug', 'is_private', 'description', 'tags',
)),
)
@@ -110,8 +112,8 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Aggregate'), ('prefix', 'rir', 'date_added', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -131,8 +133,8 @@ class ASNRangeForm(TenancyForm, NetBoxModelForm):
)
slug = SlugField()
fieldsets = (
- ('ASN Range', ('name', 'slug', 'rir', 'start', 'end', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('ASN Range'), ('name', 'slug', 'rir', 'start', 'end', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -155,8 +157,8 @@ class ASNForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('ASN', ('asn', 'rir', 'sites', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('ASN'), ('asn', 'rir', 'sites', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -184,7 +186,7 @@ class RoleForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Role', (
+ (_('Role'), (
'name', 'slug', 'weight', 'description', 'tags',
)),
)
@@ -203,6 +205,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
label=_('VRF')
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
selector=True,
@@ -215,15 +218,16 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
label=_('VLAN'),
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
- ('Site/VLAN Assignment', ('site', 'vlan')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Prefix'), ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
+ (_('Site/VLAN Assignment'), ('site', 'vlan')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -241,14 +245,15 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
label=_('VRF')
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'mark_utilized', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('IP Range'), ('vrf', 'start_address', 'end_address', 'role', 'status', 'mark_utilized', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -261,6 +266,7 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
class IPAddressForm(TenancyForm, NetBoxModelForm):
interface = DynamicModelChoiceField(
+ label=_('Interface'),
queryset=Interface.objects.all(),
required=False,
selector=True,
@@ -341,13 +347,13 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
]
if len(selected_objects) > 1:
raise forms.ValidationError({
- selected_objects[1]: "An IP address can only be assigned to a single object."
+ selected_objects[1]: _("An IP address can only be assigned to a single object.")
})
elif selected_objects:
assigned_object = self.cleaned_data[selected_objects[0]]
if self.instance.pk and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object:
raise ValidationError(
- "Cannot reassign IP address while it is designated as the primary IP for the parent object"
+ _("Cannot reassign IP address while it is designated as the primary IP for the parent object")
)
self.instance.assigned_object = assigned_object
else:
@@ -357,19 +363,21 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
if self.cleaned_data.get('primary_for_parent') and not interface:
self.add_error(
- 'primary_for_parent', "Only IP addresses assigned to an interface can be designated as primary IPs."
+ 'primary_for_parent', _("Only IP addresses assigned to an interface can be designated as primary IPs.")
)
# Do not allow assigning a network ID or broadcast address to an interface.
if interface and (address := self.cleaned_data.get('address')):
if address.ip == address.network:
- msg = f"{address} is a network ID, which may not be assigned to an interface."
+ msg = _("{address} is a network ID, which may not be assigned to an interface.").format(address=address)
if address.version == 4 and address.prefixlen not in (31, 32):
raise ValidationError(msg)
if address.version == 6 and address.prefixlen not in (127, 128):
raise ValidationError(msg)
if address.version == 4 and address.ip == address.broadcast and address.prefixlen not in (31, 32):
- msg = f"{address} is a broadcast address, which may not be assigned to an interface."
+ msg = _("{address} is a broadcast address, which may not be assigned to an interface.").format(
+ address=address
+ )
raise ValidationError(msg)
def save(self, *args, **kwargs):
@@ -442,9 +450,9 @@ class FHRPGroupForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('FHRP Group', ('protocol', 'group_id', 'name', 'description', 'tags')),
- ('Authentication', ('auth_type', 'auth_key')),
- ('Virtual IP Address', ('ip_vrf', 'ip_address', 'ip_status'))
+ (_('FHRP Group'), ('protocol', 'group_id', 'name', 'description', 'tags')),
+ (_('Authentication'), ('auth_type', 'auth_key')),
+ (_('Virtual IP Address'), ('ip_vrf', 'ip_address', 'ip_status'))
)
class Meta:
@@ -497,6 +505,7 @@ class FHRPGroupForm(NetBoxModelForm):
class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=FHRPGroup.objects.all()
)
@@ -514,10 +523,12 @@ class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):
class VLANGroupForm(NetBoxModelForm):
scope_type = ContentTypeChoiceField(
+ label=_('Scope type'),
queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
required=False
)
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
initial_params={
@@ -533,6 +544,7 @@ class VLANGroupForm(NetBoxModelForm):
label=_('Site group')
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
initial_params={
@@ -544,6 +556,7 @@ class VLANGroupForm(NetBoxModelForm):
}
)
location = DynamicModelChoiceField(
+ label=_('Location'),
queryset=Location.objects.all(),
required=False,
initial_params={
@@ -554,6 +567,7 @@ class VLANGroupForm(NetBoxModelForm):
}
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
query_params={
@@ -570,6 +584,7 @@ class VLANGroupForm(NetBoxModelForm):
label=_('Cluster group')
)
cluster = DynamicModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
required=False,
query_params={
@@ -579,9 +594,9 @@ class VLANGroupForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('VLAN Group', ('name', 'slug', 'description', 'tags')),
- ('Child VLANs', ('min_vid', 'max_vid')),
- ('Scope', ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')),
+ (_('VLAN Group'), ('name', 'slug', 'description', 'tags')),
+ (_('Child VLANs'), ('min_vid', 'max_vid')),
+ (_('Scope'), ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')),
)
class Meta:
@@ -621,12 +636,14 @@ class VLANForm(TenancyForm, NetBoxModelForm):
label=_('VLAN Group')
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
null_option='None',
selector=True
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=Role.objects.all(),
required=False
)
@@ -642,6 +659,7 @@ class VLANForm(TenancyForm, NetBoxModelForm):
class ServiceTemplateForm(NetBoxModelForm):
ports = NumericArrayField(
+ label=_('Ports'),
base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX
@@ -651,7 +669,7 @@ class ServiceTemplateForm(NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Service Template', (
+ (_('Service Template'), (
'name', 'protocol', 'ports', 'description', 'tags',
)),
)
@@ -663,16 +681,19 @@ class ServiceTemplateForm(NetBoxModelForm):
class ServiceForm(NetBoxModelForm):
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
selector=True
)
virtual_machine = DynamicModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
required=False,
selector=True
)
ports = NumericArrayField(
+ label=_('Ports'),
base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX
@@ -699,6 +720,7 @@ class ServiceForm(NetBoxModelForm):
class ServiceCreateForm(ServiceForm):
service_template = DynamicModelChoiceField(
+ label=_('Service template'),
queryset=ServiceTemplate.objects.all(),
required=False
)
@@ -739,19 +761,21 @@ class ServiceCreateForm(ServiceForm):
class L2VPNForm(TenancyForm, NetBoxModelForm):
slug = SlugField()
import_targets = DynamicModelMultipleChoiceField(
+ label=_('Import targets'),
queryset=RouteTarget.objects.all(),
required=False
)
export_targets = DynamicModelMultipleChoiceField(
+ label=_('Export targets'),
queryset=RouteTarget.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('L2VPN', ('name', 'slug', 'type', 'identifier', 'description', 'tags')),
- ('Route Targets', ('import_targets', 'export_targets')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('L2VPN'), ('name', 'slug', 'type', 'identifier', 'description', 'tags')),
+ (_('Route Targets'), ('import_targets', 'export_targets')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -777,6 +801,7 @@ class L2VPNTerminationForm(NetBoxModelForm):
label=_('VLAN')
)
interface = DynamicModelChoiceField(
+ label=_('Interface'),
queryset=Interface.objects.all(),
required=False,
selector=True
@@ -815,8 +840,8 @@ class L2VPNTerminationForm(NetBoxModelForm):
vlan = self.cleaned_data.get('vlan')
if not (interface or vminterface or vlan):
- raise ValidationError('A termination must specify an interface or VLAN.')
+ raise ValidationError(_('A termination must specify an interface or VLAN.'))
if len([x for x in (interface, vminterface, vlan) if x]) > 1:
- raise ValidationError('A termination can only have one terminating object (an interface or VLAN).')
+ raise ValidationError(_('A termination can only have one terminating object (an interface or VLAN).'))
self.instance.assigned_object = interface or vminterface or vlan
diff --git a/netbox/netbox/forms/base.py b/netbox/netbox/forms/base.py
index 88cec405f..efa93c37c 100644
--- a/netbox/netbox/forms/base.py
+++ b/netbox/netbox/forms/base.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices, CustomFieldVisibilityChoices
from extras.forms.mixins import CustomFieldsMixin, SavedFiltersMixin
@@ -28,7 +28,8 @@ class NetBoxModelForm(BootstrapMixin, CustomFieldsMixin, forms.ModelForm):
fieldsets = ()
tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(),
- required=False
+ required=False,
+ label=_('Tags'),
)
def __init__(self, *args, **kwargs):
@@ -73,10 +74,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',
@@ -109,10 +112,12 @@ class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
widget=forms.MultipleHiddenInput
)
add_tags = DynamicModelMultipleChoiceField(
+ label=_('Add tags'),
queryset=Tag.objects.all(),
required=False
)
remove_tags = DynamicModelMultipleChoiceField(
+ label=_('Remove tags'),
queryset=Tag.objects.all(),
required=False
)
diff --git a/netbox/tenancy/forms/bulk_edit.py b/netbox/tenancy/forms/bulk_edit.py
index 34ca35239..49866ca3e 100644
--- a/netbox/tenancy/forms/bulk_edit.py
+++ b/netbox/tenancy/forms/bulk_edit.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelBulkEditForm
from tenancy.choices import ContactPriorityChoices
@@ -22,10 +23,12 @@ __all__ = (
class TenantGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=TenantGroup.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -36,6 +39,7 @@ class TenantGroupBulkEditForm(NetBoxModelBulkEditForm):
class TenantBulkEditForm(NetBoxModelBulkEditForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=TenantGroup.objects.all(),
required=False
)
@@ -53,10 +57,12 @@ class TenantBulkEditForm(NetBoxModelBulkEditForm):
class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=ContactGroup.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Desciption'),
max_length=200,
required=False
)
@@ -70,6 +76,7 @@ class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -83,34 +90,39 @@ class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
class ContactBulkEditForm(NetBoxModelBulkEditForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=ContactGroup.objects.all(),
required=False
)
title = forms.CharField(
+ label=_('Title'),
max_length=100,
required=False
)
phone = forms.CharField(
+ label=_('Phone'),
max_length=50,
required=False
)
email = forms.EmailField(
+ label=_('Email'),
required=False
)
address = forms.CharField(
+ label=_('Address'),
max_length=200,
required=False
)
link = forms.URLField(
+ label=_('Link'),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = Contact
fieldsets = (
@@ -121,14 +133,17 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
class ContactAssignmentBulkEditForm(NetBoxModelBulkEditForm):
contact = DynamicModelChoiceField(
+ label=_('Contact'),
queryset=Contact.objects.all(),
required=False
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=ContactRole.objects.all(),
required=False
)
priority = forms.ChoiceField(
+ label=_('Priority'),
choices=add_blank_choice(ContactPriorityChoices),
required=False
)
diff --git a/netbox/tenancy/forms/bulk_import.py b/netbox/tenancy/forms/bulk_import.py
index 0aec0e28f..6a5eb05bf 100644
--- a/netbox/tenancy/forms/bulk_import.py
+++ b/netbox/tenancy/forms/bulk_import.py
@@ -1,5 +1,6 @@
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
+
from netbox.forms import NetBoxModelImportForm
from tenancy.models import *
from utilities.forms.fields import CSVContentTypeField, CSVModelChoiceField, SlugField
@@ -20,6 +21,7 @@ __all__ = (
class TenantGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=TenantGroup.objects.all(),
required=False,
to_field_name='name',
@@ -35,6 +37,7 @@ class TenantGroupImportForm(NetBoxModelImportForm):
class TenantImportForm(NetBoxModelImportForm):
slug = SlugField()
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=TenantGroup.objects.all(),
required=False,
to_field_name='name',
@@ -52,6 +55,7 @@ class TenantImportForm(NetBoxModelImportForm):
class ContactGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=ContactGroup.objects.all(),
required=False,
to_field_name='name',
@@ -74,6 +78,7 @@ class ContactRoleImportForm(NetBoxModelImportForm):
class ContactImportForm(NetBoxModelImportForm):
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=ContactGroup.objects.all(),
required=False,
to_field_name='name',
diff --git a/netbox/tenancy/forms/filtersets.py b/netbox/tenancy/forms/filtersets.py
index 626d26785..6ad473fa8 100644
--- a/netbox/tenancy/forms/filtersets.py
+++ b/netbox/tenancy/forms/filtersets.py
@@ -1,6 +1,6 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from extras.utils import FeatureQuery
from netbox.forms import NetBoxModelFilterSetForm
@@ -84,7 +84,7 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm):
model = ContactAssignment
fieldsets = (
(None, ('q', 'filter_id')),
- ('Assignment', ('content_type_id', 'group_id', 'contact_id', 'role_id', 'priority')),
+ (_('Assignment'), ('content_type_id', 'group_id', 'contact_id', 'role_id', 'priority')),
)
content_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(),
@@ -108,6 +108,7 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm):
label=_('Role')
)
priority = forms.MultipleChoiceField(
+ label=_('Priority'),
choices=ContactPriorityChoices,
required=False
)
diff --git a/netbox/tenancy/forms/forms.py b/netbox/tenancy/forms/forms.py
index 789566e94..114253e7a 100644
--- a/netbox/tenancy/forms/forms.py
+++ b/netbox/tenancy/forms/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from tenancy.models import *
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
@@ -13,6 +13,7 @@ __all__ = (
class TenancyForm(forms.Form):
tenant_group = DynamicModelChoiceField(
+ label=_('Tenant group'),
queryset=TenantGroup.objects.all(),
required=False,
null_option='None',
@@ -21,6 +22,7 @@ class TenancyForm(forms.Form):
}
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
query_params={
diff --git a/netbox/tenancy/forms/model_forms.py b/netbox/tenancy/forms/model_forms.py
index 6d6534d40..41a202c7f 100644
--- a/netbox/tenancy/forms/model_forms.py
+++ b/netbox/tenancy/forms/model_forms.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelForm
from tenancy.models import *
@@ -21,13 +22,14 @@ __all__ = (
class TenantGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=TenantGroup.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Tenant Group', (
+ (_('Tenant Group'), (
'parent', 'name', 'slug', 'description', 'tags',
)),
)
@@ -42,13 +44,14 @@ class TenantGroupForm(NetBoxModelForm):
class TenantForm(NetBoxModelForm):
slug = SlugField()
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=TenantGroup.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('Tenant', ('name', 'slug', 'group', 'description', 'tags')),
+ (_('Tenant'), ('name', 'slug', 'group', 'description', 'tags')),
)
class Meta:
@@ -64,13 +67,14 @@ class TenantForm(NetBoxModelForm):
class ContactGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=ContactGroup.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Contact Group', (
+ (_('Contact Group'), (
'parent', 'name', 'slug', 'description', 'tags',
)),
)
@@ -84,7 +88,7 @@ class ContactRoleForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Contact Role', (
+ (_('Contact Role'), (
'name', 'slug', 'description', 'tags',
)),
)
@@ -96,13 +100,14 @@ class ContactRoleForm(NetBoxModelForm):
class ContactForm(NetBoxModelForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=ContactGroup.objects.all(),
required=False
)
comments = CommentField()
fieldsets = (
- ('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')),
+ (_('Contact'), ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')),
)
class Meta:
@@ -117,6 +122,7 @@ class ContactForm(NetBoxModelForm):
class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=ContactGroup.objects.all(),
required=False,
initial_params={
@@ -124,12 +130,14 @@ class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
}
)
contact = DynamicModelChoiceField(
+ label=_('Contact'),
queryset=Contact.objects.all(),
query_params={
'group_id': '$group'
}
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=ContactRole.objects.all()
)
diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py
index 6ca050110..1cc94b944 100644
--- a/netbox/users/forms/model_forms.py
+++ b/netbox/users/forms/model_forms.py
@@ -66,7 +66,6 @@ class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMe
)
# List of clearable preferences
pk = forms.MultipleChoiceField(
- label=_('Pk'),
choices=[],
required=False
)
diff --git a/netbox/utilities/forms/fields/array.py b/netbox/utilities/forms/fields/array.py
index 6e1a40988..14f122453 100644
--- a/netbox/utilities/forms/fields/array.py
+++ b/netbox/utilities/forms/fields/array.py
@@ -1,5 +1,6 @@
from django import forms
from django.contrib.postgres.forms import SimpleArrayField
+from django.utils.translation import gettext_lazy as _
from ..utils import parse_numeric_range
@@ -12,8 +13,9 @@ class NumericArrayField(SimpleArrayField):
def clean(self, value):
if value and not self.to_python(value):
- raise forms.ValidationError(f'Invalid list ({value}). '
- f'Must be numeric and ranges must be in ascending order')
+ raise forms.ValidationError(
+ _("Invalid list ({value}). Must be numeric and ranges must be in ascending order.").format(value=value)
+ )
return super().clean(value)
def to_python(self, value):
diff --git a/netbox/utilities/forms/fields/csv.py b/netbox/utilities/forms/fields/csv.py
index 5d6258193..97d772412 100644
--- a/netbox/utilities/forms/fields/csv.py
+++ b/netbox/utilities/forms/fields/csv.py
@@ -1,4 +1,5 @@
from django import forms
+from django.utils.translation import gettext_lazy as _
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import Q
@@ -40,7 +41,7 @@ class CSVMultipleChoiceField(CSVChoicesMixin, forms.MultipleChoiceField):
if not value:
return []
if not isinstance(value, str):
- raise forms.ValidationError(f"Invalid value for a multiple choice field: {value}")
+ raise forms.ValidationError(_("Invalid value for a multiple choice field: {value}").format(value=value))
return value.split(',')
@@ -53,7 +54,7 @@ class CSVModelChoiceField(forms.ModelChoiceField):
Extends Django's `ModelChoiceField` to provide additional validation for CSV values.
"""
default_error_messages = {
- 'invalid_choice': 'Object not found: %(value)s',
+ 'invalid_choice': _('Object not found: %(value)s'),
}
def to_python(self, value):
@@ -61,7 +62,7 @@ class CSVModelChoiceField(forms.ModelChoiceField):
return super().to_python(value)
except MultipleObjectsReturned:
raise forms.ValidationError(
- f'"{value}" is not a unique value for this field; multiple objects were found'
+ _('"{value}" is not a unique value for this field; multiple objects were found').format(value=value)
)
@@ -70,7 +71,7 @@ class CSVModelMultipleChoiceField(forms.ModelMultipleChoiceField):
Extends Django's `ModelMultipleChoiceField` to support comma-separated values.
"""
default_error_messages = {
- 'invalid_choice': 'Object not found: %(value)s',
+ 'invalid_choice': _('Object not found: %(value)s'),
}
def clean(self, value):
@@ -93,11 +94,11 @@ class CSVContentTypeField(CSVModelChoiceField):
try:
app_label, model = value.split('.')
except ValueError:
- raise forms.ValidationError(f'Object type must be specified as "."')
+ raise forms.ValidationError(_('Object type must be specified as "."'))
try:
return self.queryset.get(app_label=app_label, model=model)
except ObjectDoesNotExist:
- raise forms.ValidationError(f'Invalid object type')
+ raise forms.ValidationError(_('Invalid object type'))
class CSVMultipleContentTypeField(forms.ModelMultipleChoiceField):
diff --git a/netbox/utilities/forms/fields/expandable.py b/netbox/utilities/forms/fields/expandable.py
index 781de9f76..959271a85 100644
--- a/netbox/utilities/forms/fields/expandable.py
+++ b/netbox/utilities/forms/fields/expandable.py
@@ -1,7 +1,7 @@
import re
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from utilities.forms.constants import *
from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
@@ -21,10 +21,10 @@ class ExpandableNameField(forms.CharField):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if not self.help_text:
- self.help_text = """
- Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range
- are not supported (example: [ge,xe]-0/0/[0-9]
).
- """
+ self.help_text = _(
+ "Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range are "
+ "not supported (example: [ge,xe]-0/0/[0-9]
)."
+ )
def to_python(self, value):
if not value:
diff --git a/netbox/utilities/forms/fields/fields.py b/netbox/utilities/forms/fields/fields.py
index c1e1e481c..db5e4a30d 100644
--- a/netbox/utilities/forms/fields/fields.py
+++ b/netbox/utilities/forms/fields/fields.py
@@ -4,7 +4,7 @@ from django import forms
from django.db.models import Count
from django.forms.fields import JSONField as _JSONField, InvalidJSONInput
from django.templatetags.static import static
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from netaddr import AddrFormatError, EUI
from utilities.forms import widgets
@@ -26,14 +26,14 @@ class CommentField(forms.CharField):
A textarea with support for Markdown rendering. Exists mostly just to add a standard `help_text`.
"""
widget = widgets.MarkdownWidget
- help_text = f"""
-
-
- Markdown syntax is supported
- """
+ label = _('Comments')
+ help_text = _(
+ ' '
+ 'Markdown syntax is supported'
+ ).format(url=static('docs/reference/markdown/'))
- def __init__(self, *, help_text=help_text, required=False, **kwargs):
- super().__init__(help_text=help_text, required=required, **kwargs)
+ def __init__(self, *, label=label, help_text=help_text, required=False, **kwargs):
+ super().__init__(label=label, help_text=help_text, required=required, **kwargs)
class SlugField(forms.SlugField):
@@ -44,10 +44,11 @@ class SlugField(forms.SlugField):
slug_source: Name of the form field from which the slug value will be derived
"""
widget = widgets.SlugWidget
+ label = _('Slug')
help_text = _("URL-friendly unique shorthand")
- def __init__(self, *, slug_source='name', help_text=help_text, **kwargs):
- super().__init__(help_text=help_text, **kwargs)
+ def __init__(self, *, slug_source='name', label=label, help_text=help_text, **kwargs):
+ super().__init__(label=label, help_text=help_text, **kwargs)
self.widget.attrs['slug-source'] = slug_source
@@ -77,7 +78,7 @@ class TagFilterField(forms.MultipleChoiceField):
]
# Choices are fetched each time the form is initialized
- super().__init__(label='Tags', choices=get_choices, required=False, *args, **kwargs)
+ super().__init__(label=_('Tags'), choices=get_choices, required=False, *args, **kwargs)
class LaxURLField(forms.URLField):
@@ -113,7 +114,7 @@ class MACAddressField(forms.Field):
"""
widget = forms.CharField
default_error_messages = {
- 'invalid': 'MAC address must be in EUI-48 format',
+ 'invalid': _('MAC address must be in EUI-48 format'),
}
def to_python(self, value):
diff --git a/netbox/virtualization/forms/bulk_create.py b/netbox/virtualization/forms/bulk_create.py
index 0b762f38e..7153453ec 100644
--- a/netbox/virtualization/forms/bulk_create.py
+++ b/netbox/virtualization/forms/bulk_create.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from utilities.forms import BootstrapMixin, form_from_model
from utilities.forms.fields import ExpandableNameField
diff --git a/netbox/virtualization/forms/bulk_edit.py b/netbox/virtualization/forms/bulk_edit.py
index 9aa771d29..cc281a4f7 100644
--- a/netbox/virtualization/forms/bulk_edit.py
+++ b/netbox/virtualization/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import InterfaceModeChoices
from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN
@@ -25,6 +25,7 @@ __all__ = (
class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -38,6 +39,7 @@ class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -51,31 +53,38 @@ class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
class ClusterBulkEditForm(NetBoxModelBulkEditForm):
type = DynamicModelChoiceField(
+ label=_('Type'),
queryset=ClusterType.objects.all(),
required=False
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=ClusterGroup.objects.all(),
required=False
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(ClusterStatusChoices),
required=False,
initial=''
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False,
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -84,17 +93,16 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
}
)
description = forms.CharField(
+ label=_('Site'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = Cluster
fieldsets = (
(None, ('type', 'group', 'status', 'tenant', 'description')),
- ('Site', ('region', 'site_group', 'site')),
+ (_('Site'), ('region', 'site_group', 'site')),
)
nullable_fields = (
'group', 'site', 'tenant', 'description', 'comments',
@@ -103,15 +111,18 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(VirtualMachineStatusChoices),
required=False,
initial='',
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False
)
cluster = DynamicModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
required=False,
query_params={
@@ -119,6 +130,7 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
}
)
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
query_params={
@@ -126,6 +138,7 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
}
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=DeviceRole.objects.filter(
vm_role=True
),
@@ -135,10 +148,12 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
}
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
platform = DynamicModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False
)
@@ -155,17 +170,16 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
label=_('Disk (GB)')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label=_('Comments')
- )
+ comments = CommentField()
model = VirtualMachine
fieldsets = (
(None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description')),
- ('Resources', ('vcpus', 'memory', 'disk'))
+ (_('Resources'), ('vcpus', 'memory', 'disk'))
)
nullable_fields = (
'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments',
@@ -174,20 +188,24 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
virtual_machine = forms.ModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
required=False,
disabled=True,
widget=forms.HiddenInput()
)
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=VMInterface.objects.all(),
required=False
)
bridge = DynamicModelChoiceField(
+ label=_('Bridge'),
queryset=VMInterface.objects.all(),
required=False
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=BulkEditNullBooleanSelect()
)
@@ -198,10 +216,12 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
label=_('MTU')
)
description = forms.CharField(
+ label=_('Description'),
max_length=100,
required=False
)
mode = forms.ChoiceField(
+ label=_('Mode'),
choices=add_blank_choice(InterfaceModeChoices),
required=False
)
@@ -235,8 +255,8 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
model = VMInterface
fieldsets = (
(None, ('mtu', 'enabled', 'vrf', 'description')),
- ('Related Interfaces', ('parent', 'bridge')),
- ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
+ (_('Related Interfaces'), ('parent', 'bridge')),
+ (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
)
nullable_fields = (
'parent', 'bridge', 'mtu', 'vrf', 'description',
diff --git a/netbox/virtualization/forms/bulk_import.py b/netbox/virtualization/forms/bulk_import.py
index 15651f2ae..19f718f03 100644
--- a/netbox/virtualization/forms/bulk_import.py
+++ b/netbox/virtualization/forms/bulk_import.py
@@ -1,4 +1,4 @@
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import InterfaceModeChoices
from dcim.models import Device, DeviceRole, Platform, Site
@@ -36,27 +36,32 @@ class ClusterGroupImportForm(NetBoxModelImportForm):
class ClusterImportForm(NetBoxModelImportForm):
type = CSVModelChoiceField(
+ label=_('Type'),
queryset=ClusterType.objects.all(),
to_field_name='name',
help_text=_('Type of cluster')
)
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=ClusterGroup.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned cluster group')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=ClusterStatusChoices,
help_text=_('Operational status')
)
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned site')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
to_field_name='name',
required=False,
@@ -70,28 +75,33 @@ class ClusterImportForm(NetBoxModelImportForm):
class VirtualMachineImportForm(NetBoxModelImportForm):
status = CSVChoiceField(
+ label=_('Status'),
choices=VirtualMachineStatusChoices,
help_text=_('Operational status')
)
site = CSVModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned site')
)
cluster = CSVModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned cluster')
)
device = CSVModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
to_field_name='name',
required=False,
help_text=_('Assigned device within cluster')
)
role = CSVModelChoiceField(
+ label=_('Role'),
queryset=DeviceRole.objects.filter(
vm_role=True
),
@@ -100,12 +110,14 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
help_text=_('Functional role')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
platform = CSVModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False,
to_field_name='name',
@@ -122,27 +134,32 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
class VMInterfaceImportForm(NetBoxModelImportForm):
virtual_machine = CSVModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
to_field_name='name'
)
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=VMInterface.objects.all(),
required=False,
to_field_name='name',
help_text=_('Parent interface')
)
bridge = CSVModelChoiceField(
+ label=_('Bridge'),
queryset=VMInterface.objects.all(),
required=False,
to_field_name='name',
help_text=_('Bridged interface')
)
mode = CSVChoiceField(
+ label=_('Mode'),
choices=InterfaceModeChoices,
required=False,
help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)')
)
vrf = CSVModelChoiceField(
+ label=_('VRF'),
queryset=VRF.objects.all(),
required=False,
to_field_name='rd',
diff --git a/netbox/virtualization/forms/filtersets.py b/netbox/virtualization/forms/filtersets.py
index 3e228742c..cd1269645 100644
--- a/netbox/virtualization/forms/filtersets.py
+++ b/netbox/virtualization/forms/filtersets.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Device, DeviceRole, Platform, Region, Site, SiteGroup
from extras.forms import LocalConfigContextFilterForm
@@ -30,7 +30,7 @@ class ClusterGroupFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
tag = TagFilterField(model)
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
@@ -38,10 +38,10 @@ class ClusterFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
model = Cluster
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('group_id', 'type_id', 'status')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Attributes'), ('group_id', 'type_id', 'status')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
type_id = DynamicModelMultipleChoiceField(
queryset=ClusterType.objects.all(),
@@ -54,6 +54,7 @@ class ClusterFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Region')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=ClusterStatusChoices,
required=False
)
@@ -90,11 +91,11 @@ class VirtualMachineFilterForm(
model = VirtualMachine
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Cluster', ('cluster_group_id', 'cluster_type_id', 'cluster_id', 'device_id')),
- ('Location', ('region_id', 'site_group_id', 'site_id')),
- ('Attributes', ('status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Contacts', ('contact', 'contact_role', 'contact_group')),
+ (_('Cluster'), ('cluster_group_id', 'cluster_type_id', 'cluster_id', 'device_id')),
+ (_('Location'), ('region_id', 'site_group_id', 'site_id')),
+ (_('Attributes'), ('status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
)
cluster_group_id = DynamicModelMultipleChoiceField(
queryset=ClusterGroup.objects.all(),
@@ -148,6 +149,7 @@ class VirtualMachineFilterForm(
label=_('Role')
)
status = forms.MultipleChoiceField(
+ label=_('Status'),
choices=VirtualMachineStatusChoices,
required=False
)
@@ -175,8 +177,8 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
model = VMInterface
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Virtual Machine', ('cluster_id', 'virtual_machine_id')),
- ('Attributes', ('enabled', 'mac_address', 'vrf_id', 'l2vpn_id')),
+ (_('Virtual Machine'), ('cluster_id', 'virtual_machine_id')),
+ (_('Attributes'), ('enabled', 'mac_address', 'vrf_id', 'l2vpn_id')),
)
cluster_id = DynamicModelMultipleChoiceField(
queryset=Cluster.objects.all(),
@@ -192,6 +194,7 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
label=_('Virtual machine')
)
enabled = forms.NullBooleanField(
+ label=_('Enabled'),
required=False,
widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES
@@ -199,12 +202,12 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
)
mac_address = forms.CharField(
required=False,
- label='MAC address'
+ label=_('MAC address')
)
vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
required=False,
- label='VRF'
+ label=_('VRF')
)
l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(),
diff --git a/netbox/virtualization/forms/model_forms.py b/netbox/virtualization/forms/model_forms.py
index b4051dec2..0c8c98f9f 100644
--- a/netbox/virtualization/forms/model_forms.py
+++ b/netbox/virtualization/forms/model_forms.py
@@ -1,7 +1,7 @@
from django import forms
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.forms.common import InterfaceCommonForm
from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site, SiteGroup
@@ -30,7 +30,7 @@ class ClusterTypeForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Cluster Type', (
+ (_('Cluster Type'), (
'name', 'slug', 'description', 'tags',
)),
)
@@ -46,7 +46,7 @@ class ClusterGroupForm(NetBoxModelForm):
slug = SlugField()
fieldsets = (
- ('Cluster Group', (
+ (_('Cluster Group'), (
'name', 'slug', 'description', 'tags',
)),
)
@@ -60,13 +60,16 @@ class ClusterGroupForm(NetBoxModelForm):
class ClusterForm(TenancyForm, NetBoxModelForm):
type = DynamicModelChoiceField(
+ label=_('Type'),
queryset=ClusterType.objects.all()
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=ClusterGroup.objects.all(),
required=False
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
selector=True
@@ -74,8 +77,8 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Cluster', ('name', 'type', 'group', 'site', 'status', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
+ (_('Cluster'), ('name', 'type', 'group', 'site', 'status', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
)
class Meta:
@@ -87,16 +90,19 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
region = DynamicModelChoiceField(
+ label=_('Region'),
queryset=Region.objects.all(),
required=False,
null_option='None'
)
site_group = DynamicModelChoiceField(
+ label=_('Site group'),
queryset=SiteGroup.objects.all(),
required=False,
null_option='None'
)
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False,
query_params={
@@ -105,6 +111,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
}
)
rack = DynamicModelChoiceField(
+ label=_('Rack'),
queryset=Rack.objects.all(),
required=False,
null_option='None',
@@ -113,6 +120,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
}
)
devices = DynamicModelMultipleChoiceField(
+ label=_('Devices'),
queryset=Device.objects.all(),
query_params={
'site_id': '$site',
@@ -142,7 +150,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
for device in self.cleaned_data.get('devices', []):
if device.site != self.cluster.site:
raise ValidationError({
- 'devices': "{} belongs to a different site ({}) than the cluster ({})".format(
+ 'devices': _("{} belongs to a different site ({}) than the cluster ({})").format(
device, device.site, self.cluster.site
)
})
@@ -157,10 +165,12 @@ class ClusterRemoveDevicesForm(ConfirmationForm):
class VirtualMachineForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField(
+ label=_('Site'),
queryset=Site.objects.all(),
required=False
)
cluster = DynamicModelChoiceField(
+ label=_('Cluster'),
queryset=Cluster.objects.all(),
required=False,
selector=True,
@@ -169,6 +179,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
}
)
device = DynamicModelChoiceField(
+ label=_('Device'),
queryset=Device.objects.all(),
required=False,
query_params={
@@ -178,6 +189,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
help_text=_("Optionally pin this VM to a specific host device within the cluster")
)
role = DynamicModelChoiceField(
+ label=_('Role'),
queryset=DeviceRole.objects.all(),
required=False,
query_params={
@@ -185,6 +197,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
}
)
platform = DynamicModelChoiceField(
+ label=_('Platform'),
queryset=Platform.objects.all(),
required=False
)
@@ -195,12 +208,12 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Virtual Machine', ('name', 'role', 'status', 'description', 'tags')),
- ('Site/Cluster', ('site', 'cluster', 'device')),
- ('Tenancy', ('tenant_group', 'tenant')),
- ('Management', ('platform', 'primary_ip4', 'primary_ip6')),
- ('Resources', ('vcpus', 'memory', 'disk')),
- ('Config Context', ('local_context_data',)),
+ (_('Virtual Machine'), ('name', 'role', 'status', 'description', 'tags')),
+ (_('Site/Cluster'), ('site', 'cluster', 'device')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
+ (_('Management'), ('platform', 'primary_ip4', 'primary_ip6')),
+ (_('Resources'), ('vcpus', 'memory', 'disk')),
+ (_('Config Context'), ('local_context_data',)),
)
class Meta:
@@ -253,6 +266,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
virtual_machine = DynamicModelChoiceField(
+ label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(),
selector=True
)
@@ -302,11 +316,11 @@ class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
)
fieldsets = (
- ('Interface', ('virtual_machine', 'name', 'description', 'tags')),
- ('Addressing', ('vrf', 'mac_address')),
- ('Operation', ('mtu', 'enabled')),
- ('Related Interfaces', ('parent', 'bridge')),
- ('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
+ (_('Interface'), ('virtual_machine', 'name', 'description', 'tags')),
+ (_('Addressing'), ('vrf', 'mac_address')),
+ (_('Operation'), ('mtu', 'enabled')),
+ (_('Related Interfaces'), ('parent', 'bridge')),
+ (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
)
class Meta:
diff --git a/netbox/virtualization/forms/object_create.py b/netbox/virtualization/forms/object_create.py
index c36ce00ee..3ea374039 100644
--- a/netbox/virtualization/forms/object_create.py
+++ b/netbox/virtualization/forms/object_create.py
@@ -1,3 +1,4 @@
+from django.utils.translation import gettext_lazy as _
from utilities.forms.fields import ExpandableNameField
from .model_forms import VMInterfaceForm
@@ -7,7 +8,9 @@ __all__ = (
class VMInterfaceCreateForm(VMInterfaceForm):
- name = ExpandableNameField()
+ name = ExpandableNameField(
+ label=_('Name'),
+ )
replication_fields = ('name',)
class Meta(VMInterfaceForm.Meta):
diff --git a/netbox/wireless/forms/bulk_edit.py b/netbox/wireless/forms/bulk_edit.py
index 4fec0b87f..43e804345 100644
--- a/netbox/wireless/forms/bulk_edit.py
+++ b/netbox/wireless/forms/bulk_edit.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import LinkStatusChoices
from ipam.models import VLAN
@@ -20,10 +20,12 @@ __all__ = (
class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=WirelessLANGroup.objects.all(),
required=False
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
@@ -37,10 +39,12 @@ class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(WirelessLANStatusChoices),
required=False
)
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=WirelessLANGroup.objects.all(),
required=False
)
@@ -55,14 +59,17 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
label=_('SSID')
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
auth_type = forms.ChoiceField(
+ label=_('Authentication type'),
choices=add_blank_choice(WirelessAuthTypeChoices),
required=False
)
auth_cipher = forms.ChoiceField(
+ label=_('Authentication cipher'),
choices=add_blank_choice(WirelessAuthCipherChoices),
required=False
)
@@ -71,17 +78,16 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
label=_('Pre-shared key')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = WirelessLAN
fieldsets = (
(None, ('group', 'ssid', 'status', 'vlan', 'tenant', 'description')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
)
nullable_fields = (
'ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
@@ -95,18 +101,22 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
label=_('SSID')
)
status = forms.ChoiceField(
+ label=_('Status'),
choices=add_blank_choice(LinkStatusChoices),
required=False
)
tenant = DynamicModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False
)
auth_type = forms.ChoiceField(
+ label=_('Authentication type'),
choices=add_blank_choice(WirelessAuthTypeChoices),
required=False
)
auth_cipher = forms.ChoiceField(
+ label=_('Authentication cipher'),
choices=add_blank_choice(WirelessAuthCipherChoices),
required=False
)
@@ -115,17 +125,16 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
label=_('Pre-shared key')
)
description = forms.CharField(
+ label=_('Description'),
max_length=200,
required=False
)
- comments = CommentField(
- label='Comments'
- )
+ comments = CommentField()
model = WirelessLink
fieldsets = (
(None, ('ssid', 'status', 'tenant', 'description')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk'))
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk'))
)
nullable_fields = (
'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
diff --git a/netbox/wireless/forms/bulk_import.py b/netbox/wireless/forms/bulk_import.py
index f29e24260..c0e2dfb54 100644
--- a/netbox/wireless/forms/bulk_import.py
+++ b/netbox/wireless/forms/bulk_import.py
@@ -1,4 +1,4 @@
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import LinkStatusChoices
from dcim.models import Interface
@@ -18,6 +18,7 @@ __all__ = (
class WirelessLANGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField(
+ label=_('Parent'),
queryset=WirelessLANGroup.objects.all(),
required=False,
to_field_name='name',
@@ -32,33 +33,39 @@ class WirelessLANGroupImportForm(NetBoxModelImportForm):
class WirelessLANImportForm(NetBoxModelImportForm):
group = CSVModelChoiceField(
+ label=_('Group'),
queryset=WirelessLANGroup.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned group')
)
status = CSVChoiceField(
+ label=_('Status'),
choices=WirelessLANStatusChoices,
help_text='Operational status'
)
vlan = CSVModelChoiceField(
+ label=_('VLAN'),
queryset=VLAN.objects.all(),
required=False,
to_field_name='name',
help_text=_('Bridged VLAN')
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
auth_type = CSVChoiceField(
+ label=_('Authentication type'),
choices=WirelessAuthTypeChoices,
required=False,
help_text=_('Authentication type')
)
auth_cipher = CSVChoiceField(
+ label=_('Authentication cipher'),
choices=WirelessAuthCipherChoices,
required=False,
help_text=_('Authentication cipher')
@@ -74,27 +81,33 @@ class WirelessLANImportForm(NetBoxModelImportForm):
class WirelessLinkImportForm(NetBoxModelImportForm):
status = CSVChoiceField(
+ label=_('Status'),
choices=LinkStatusChoices,
help_text=_('Connection status')
)
interface_a = CSVModelChoiceField(
+ label=_('Interface A'),
queryset=Interface.objects.all()
)
interface_b = CSVModelChoiceField(
+ label=_('Interface B'),
queryset=Interface.objects.all()
)
tenant = CSVModelChoiceField(
+ label=_('Tenant'),
queryset=Tenant.objects.all(),
required=False,
to_field_name='name',
help_text=_('Assigned tenant')
)
auth_type = CSVChoiceField(
+ label=_('Authentication type'),
choices=WirelessAuthTypeChoices,
required=False,
help_text=_('Authentication type')
)
auth_cipher = CSVChoiceField(
+ label=_('Authentication cipher'),
choices=WirelessAuthCipherChoices,
required=False,
help_text=_('Authentication cipher')
diff --git a/netbox/wireless/forms/filtersets.py b/netbox/wireless/forms/filtersets.py
index f281ed0db..f4c1cb523 100644
--- a/netbox/wireless/forms/filtersets.py
+++ b/netbox/wireless/forms/filtersets.py
@@ -1,5 +1,5 @@
from django import forms
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.choices import LinkStatusChoices
from netbox.forms import NetBoxModelFilterSetForm
@@ -30,9 +30,9 @@ class WirelessLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = WirelessLAN
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('ssid', 'group_id', 'status')),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+ (_('Attributes'), ('ssid', 'group_id', 'status')),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
)
ssid = forms.CharField(
required=False,
@@ -45,18 +45,22 @@ class WirelessLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Group')
)
status = forms.ChoiceField(
+ label=_('Status'),
required=False,
choices=add_blank_choice(WirelessLANStatusChoices)
)
auth_type = forms.ChoiceField(
+ label=_('Authentication type'),
required=False,
choices=add_blank_choice(WirelessAuthTypeChoices)
)
auth_cipher = forms.ChoiceField(
+ label=_('Authentication cipher'),
required=False,
choices=add_blank_choice(WirelessAuthCipherChoices)
)
auth_psk = forms.CharField(
+ label=_('Pre-shared key'),
required=False
)
tag = TagFilterField(model)
@@ -66,27 +70,31 @@ class WirelessLinkFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = WirelessLink
fieldsets = (
(None, ('q', 'filter_id', 'tag')),
- ('Attributes', ('ssid', 'status',)),
- ('Tenant', ('tenant_group_id', 'tenant_id')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+ (_('Attributes'), ('ssid', 'status',)),
+ (_('Tenant'), ('tenant_group_id', 'tenant_id')),
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
)
ssid = forms.CharField(
required=False,
label=_('SSID')
)
status = forms.ChoiceField(
+ label=_('Status'),
required=False,
choices=add_blank_choice(LinkStatusChoices)
)
auth_type = forms.ChoiceField(
+ label=_('Authentication type'),
required=False,
choices=add_blank_choice(WirelessAuthTypeChoices)
)
auth_cipher = forms.ChoiceField(
+ label=_('Authentication cipher'),
required=False,
choices=add_blank_choice(WirelessAuthCipherChoices)
)
auth_psk = forms.CharField(
+ label=_('Pre-shared key'),
required=False
)
tag = TagFilterField(model)
diff --git a/netbox/wireless/forms/model_forms.py b/netbox/wireless/forms/model_forms.py
index 2523ff7a9..666bddaa9 100644
--- a/netbox/wireless/forms/model_forms.py
+++ b/netbox/wireless/forms/model_forms.py
@@ -1,5 +1,5 @@
from django.forms import PasswordInput
-from django.utils.translation import gettext as _
+from django.utils.translation import gettext_lazy as _
from dcim.models import Device, Interface, Location, Site
from ipam.models import VLAN
@@ -17,13 +17,14 @@ __all__ = (
class WirelessLANGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField(
+ label=_('Parent'),
queryset=WirelessLANGroup.objects.all(),
required=False
)
slug = SlugField()
fieldsets = (
- ('Wireless LAN Group', (
+ (_('Wireless LAN Group'), (
'parent', 'name', 'slug', 'description', 'tags',
)),
)
@@ -37,6 +38,7 @@ class WirelessLANGroupForm(NetBoxModelForm):
class WirelessLANForm(TenancyForm, NetBoxModelForm):
group = DynamicModelChoiceField(
+ label=_('Group'),
queryset=WirelessLANGroup.objects.all(),
required=False
)
@@ -49,9 +51,9 @@ class WirelessLANForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Wireless LAN', ('ssid', 'group', 'vlan', 'status', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+ (_('Wireless LAN'), ('ssid', 'group', 'vlan', 'status', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
)
class Meta:
@@ -152,11 +154,11 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm):
comments = CommentField()
fieldsets = (
- ('Side A', ('site_a', 'location_a', 'device_a', 'interface_a')),
- ('Side B', ('site_b', 'location_b', 'device_b', 'interface_b')),
- ('Link', ('status', 'ssid', 'description', 'tags')),
- ('Tenancy', ('tenant_group', 'tenant')),
- ('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')),
+ (_('Side A'), ('site_a', 'location_a', 'device_a', 'interface_a')),
+ (_('Side B'), ('site_b', 'location_b', 'device_b', 'interface_b')),
+ (_('Link'), ('status', 'ssid', 'description', 'tags')),
+ (_('Tenancy'), ('tenant_group', 'tenant')),
+ (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
)
class Meta: