From b6e50b789c69ab36bdb4891da44b2bd1aa21ee6c Mon Sep 17 00:00:00 2001 From: Arthur Date: Thu, 13 Jul 2023 14:42:16 +0700 Subject: [PATCH] 13149 add gettext_lazy to forms --- netbox/ipam/forms/bulk_create.py | 2 +- netbox/ipam/forms/bulk_edit.py | 86 +++++++++++++++---- netbox/ipam/forms/bulk_import.py | 72 +++++++++++++--- netbox/ipam/forms/filtersets.py | 87 +++++++++++-------- netbox/ipam/forms/model_forms.py | 139 +++++++++++++++++++++---------- 5 files changed, 274 insertions(+), 112 deletions(-) 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..aef236cd5 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,11 +47,12 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm): label=_('Enforce unique space') ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) comments = CommentField( - label='Comments' + label=_('Comments') ) model = VRF @@ -62,15 +64,17 @@ 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' + label=_('Comments') ) model = RouteTarget @@ -82,10 +86,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 +110,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 +129,7 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm): class ASNBulkEditForm(NetBoxModelBulkEditForm): sites = DynamicModelMultipleChoiceField( + label=_('Sites'), queryset=Site.objects.all(), required=False ) @@ -130,15 +139,17 @@ 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' + label=_('Comments') ) model = ASN @@ -155,18 +166,21 @@ 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' + label=_('Comments') ) model = Aggregate @@ -178,9 +192,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 +210,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 +234,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 +265,19 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm): label=_('Treat as 100% utilized') ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) comments = CommentField( - label='Comments' + label=_('Comments') ) 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 +291,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,11 +311,12 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm): label=_('Treat as 100% utilized') ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) comments = CommentField( - label='Comments' + label=_('Comments') ) model = IPRange @@ -307,19 +335,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 +361,18 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm): label=_('DNS name') ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) comments = CommentField( - label='Comments' + label=_('Comments') ) 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 +381,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm): class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm): protocol = forms.ChoiceField( + label=_('Protocol'), choices=add_blank_choice(FHRPGroupProtocolChoices), required=False ) @@ -367,27 +401,30 @@ 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' + label=_('Comments') ) 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 +441,7 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm): label=_('Maximum child VLAN VID') ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) @@ -417,14 +455,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 +474,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm): } ) group = DynamicModelChoiceField( + label=_('Group'), queryset=VLANGroup.objects.all(), required=False, query_params={ @@ -440,29 +482,33 @@ 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' + label=_('Comments') ) 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 +517,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,11 +530,12 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm): required=False ) description = forms.CharField( + label=_('Description'), max_length=200, required=False ) comments = CommentField( - label='Comments' + label=_('Comments') ) model = ServiceTemplate @@ -502,19 +551,22 @@ 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' + label=_('Comments') ) model = L2VPN diff --git a/netbox/ipam/forms/bulk_import.py b/netbox/ipam/forms/bulk_import.py index 683d40f49..ee65e2872 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', @@ -61,7 +63,9 @@ class RouteTargetImportForm(NetBoxModelImportForm): class RIRImportForm(NetBoxModelImportForm): - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) class Meta: model = RIR @@ -70,11 +74,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 +94,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 +114,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', @@ -123,7 +133,9 @@ class ASNImportForm(NetBoxModelImportForm): class RoleImportForm(NetBoxModelImportForm): - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) class Meta: model = Role @@ -132,40 +144,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 +230,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 +266,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 +352,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 +381,11 @@ class IPAddressImportForm(NetBoxModelImportForm): class FHRPGroupImportForm(NetBoxModelImportForm): protocol = CSVChoiceField( + label=_('Protocol'), choices=FHRPGroupProtocolChoices ) auth_type = CSVChoiceField( + label=_('Auth type'), choices=FHRPGroupAuthTypeChoices, required=False ) @@ -363,7 +396,9 @@ class FHRPGroupImportForm(NetBoxModelImportForm): class VLANGroupImportForm(NetBoxModelImportForm): - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) scope_type = CSVContentTypeField( queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES), required=False, @@ -373,13 +408,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: {vlan_min})').format(vlan_min=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: {vlan_min})').format(vlan_min=VLAN_VID_MIN) ) class Meta: @@ -392,28 +427,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 +467,7 @@ class VLANImportForm(NetBoxModelImportForm): class ServiceTemplateImportForm(NetBoxModelImportForm): protocol = CSVChoiceField( + label=_('Protocol'), choices=ServiceProtocolChoices, help_text=_('IP protocol') ) @@ -438,18 +479,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 +505,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 +530,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 +581,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..89de30f0a 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,12 +167,13 @@ 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( + label=_('Mask length'), widget=forms.HiddenInput() ) within_include = forms.CharField( @@ -204,6 +207,7 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): label=_('Present in VRF') ) status = forms.MultipleChoiceField( + label=_('Status'), choices=PrefixStatusChoices, required=False ) @@ -253,8 +257,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 +272,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): null_option='Global' ) status = forms.MultipleChoiceField( + label=_('Status'), choices=IPRangeStatusChoices, required=False ) @@ -291,10 +296,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 +342,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 +365,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 +397,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 +445,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 +478,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): label=_('VLAN group') ) status = forms.MultipleChoiceField( + label=_('Status'), choices=VLANStatusChoices, required=False ) @@ -480,7 +490,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 +504,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 +527,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 +552,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..68a6a7325 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,23 @@ __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() + comments = CommentField( + label=_('Comments'), + ) 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: @@ -77,7 +81,9 @@ class RouteTargetForm(TenancyForm, NetBoxModelForm): ('Route Target', ('name', 'description', 'tags')), ('Tenancy', ('tenant_group', 'tenant')), ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) class Meta: model = RouteTarget @@ -87,10 +93,12 @@ class RouteTargetForm(TenancyForm, NetBoxModelForm): class RIRForm(NetBoxModelForm): - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) fieldsets = ( - ('RIR', ( + (_('RIR'), ( 'name', 'slug', 'is_private', 'description', 'tags', )), ) @@ -107,11 +115,13 @@ class AggregateForm(TenancyForm, NetBoxModelForm): queryset=RIR.objects.all(), label=_('RIR') ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) 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: @@ -129,10 +139,12 @@ class ASNRangeForm(TenancyForm, NetBoxModelForm): queryset=RIR.objects.all(), label=_('RIR'), ) - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) 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: @@ -152,11 +164,13 @@ class ASNForm(TenancyForm, NetBoxModelForm): label=_('Sites'), required=False ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) 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 +198,7 @@ class RoleForm(NetBoxModelForm): slug = SlugField() fieldsets = ( - ('Role', ( + (_('Role'), ( 'name', 'slug', 'weight', 'description', 'tags', )), ) @@ -203,6 +217,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm): label=_('VRF') ) site = DynamicModelChoiceField( + label=_('Site'), queryset=Site.objects.all(), required=False, selector=True, @@ -215,15 +230,18 @@ class PrefixForm(TenancyForm, NetBoxModelForm): label=_('VLAN'), ) role = DynamicModelChoiceField( + label=_('Role'), queryset=Role.objects.all(), required=False ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) 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 +259,17 @@ class IPRangeForm(TenancyForm, NetBoxModelForm): label=_('VRF') ) role = DynamicModelChoiceField( + label=_('Role'), queryset=Role.objects.all(), required=False ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) 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 +282,7 @@ class IPRangeForm(TenancyForm, NetBoxModelForm): class IPAddressForm(TenancyForm, NetBoxModelForm): interface = DynamicModelChoiceField( + label=_('Interface'), queryset=Interface.objects.all(), required=False, selector=True, @@ -341,13 +363,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 +379,19 @@ 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 +464,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 +519,7 @@ class FHRPGroupForm(NetBoxModelForm): class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm): group = DynamicModelChoiceField( + label=_('Group'), queryset=FHRPGroup.objects.all() ) @@ -514,10 +537,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 +558,7 @@ class VLANGroupForm(NetBoxModelForm): label=_('Site group') ) site = DynamicModelChoiceField( + label=_('Site'), queryset=Site.objects.all(), required=False, initial_params={ @@ -544,6 +570,7 @@ class VLANGroupForm(NetBoxModelForm): } ) location = DynamicModelChoiceField( + label=_('Location'), queryset=Location.objects.all(), required=False, initial_params={ @@ -554,6 +581,7 @@ class VLANGroupForm(NetBoxModelForm): } ) rack = DynamicModelChoiceField( + label=_('Rack'), queryset=Rack.objects.all(), required=False, query_params={ @@ -570,18 +598,21 @@ class VLANGroupForm(NetBoxModelForm): label=_('Cluster group') ) cluster = DynamicModelChoiceField( + label=_('Cluster'), queryset=Cluster.objects.all(), required=False, query_params={ 'group_id': '$clustergroup', } ) - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) 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 +652,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,16 +675,19 @@ 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 ), help_text=_("Comma-separated list of one or more port numbers. A range may be specified using a hyphen.") ) - comments = CommentField() + comments = CommentField( + label=_('Comments'), + ) fieldsets = ( - ('Service Template', ( + (_('Service Template'), ( 'name', 'protocol', 'ports', 'description', 'tags', )), ) @@ -663,16 +699,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 +738,7 @@ class ServiceForm(NetBoxModelForm): class ServiceCreateForm(ServiceForm): service_template = DynamicModelChoiceField( + label=_('Service template'), queryset=ServiceTemplate.objects.all(), required=False ) @@ -737,21 +777,27 @@ class ServiceCreateForm(ServiceForm): class L2VPNForm(TenancyForm, NetBoxModelForm): - slug = SlugField() + slug = SlugField( + label=_('Slug'), + ) 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() + comments = CommentField( + label=_('Comments'), + ) 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 +823,7 @@ class L2VPNTerminationForm(NetBoxModelForm): label=_('VLAN') ) interface = DynamicModelChoiceField( + label=_('Interface'), queryset=Interface.objects.all(), required=False, selector=True @@ -815,8 +862,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