Closes #13149: Wrap form field labels with gettext_lazy()

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
Arthur Hanson 2023-07-31 23:52:38 +07:00 committed by GitHub
parent 83bebc1bd2
commit b7a9649269
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
51 changed files with 1381 additions and 601 deletions

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import CircuitCommitRateChoices, CircuitStatusChoices
from circuits.models import * from circuits.models import *
@ -26,12 +26,11 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = Provider model = Provider
fieldsets = ( fieldsets = (
@ -44,16 +43,16 @@ class ProviderBulkEditForm(NetBoxModelBulkEditForm):
class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm): class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm):
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = ProviderAccount model = ProviderAccount
fieldsets = ( fieldsets = (
@ -66,6 +65,7 @@ class ProviderAccountBulkEditForm(NetBoxModelBulkEditForm):
class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm): class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
required=False required=False
) )
@ -75,12 +75,11 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
label=_('Service ID') label=_('Service ID')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = ProviderNetwork model = ProviderNetwork
fieldsets = ( fieldsets = (
@ -93,6 +92,7 @@ class ProviderNetworkBulkEditForm(NetBoxModelBulkEditForm):
class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm): class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -106,14 +106,17 @@ class CircuitTypeBulkEditForm(NetBoxModelBulkEditForm):
class CircuitBulkEditForm(NetBoxModelBulkEditForm): class CircuitBulkEditForm(NetBoxModelBulkEditForm):
type = DynamicModelChoiceField( type = DynamicModelChoiceField(
label=_('Type'),
queryset=CircuitType.objects.all(), queryset=CircuitType.objects.all(),
required=False required=False
) )
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
required=False required=False
) )
provider_account = DynamicModelChoiceField( provider_account = DynamicModelChoiceField(
label=_('Provider account'),
queryset=ProviderAccount.objects.all(), queryset=ProviderAccount.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -121,19 +124,23 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(CircuitStatusChoices), choices=add_blank_choice(CircuitStatusChoices),
required=False, required=False,
initial='' initial=''
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
install_date = forms.DateField( install_date = forms.DateField(
label=_('Install date'),
required=False, required=False,
widget=DatePicker() widget=DatePicker()
) )
termination_date = forms.DateField( termination_date = forms.DateField(
label=_('Termination date'),
required=False, required=False,
widget=DatePicker() widget=DatePicker()
) )
@ -145,18 +152,17 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
) )
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=100, max_length=100,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = Circuit model = Circuit
fieldsets = ( fieldsets = (
('Circuit', ('provider', 'type', 'status', 'description')), (_('Circuit'), ('provider', 'type', 'status', 'description')),
('Service Parameters', ('provider_account', 'install_date', 'termination_date', 'commit_rate')), (_('Service Parameters'), ('provider_account', 'install_date', 'termination_date', 'commit_rate')),
('Tenancy', ('tenant',)), (_('Tenancy'), ('tenant',)),
) )
nullable_fields = ( nullable_fields = (
'tenant', 'commit_rate', 'description', 'comments', 'tenant', 'commit_rate', 'description', 'comments',

View File

@ -3,7 +3,7 @@ from django import forms
from circuits.choices import CircuitStatusChoices from circuits.choices import CircuitStatusChoices
from circuits.models import * from circuits.models import *
from dcim.models import Site 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 netbox.forms import NetBoxModelImportForm
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.forms import BootstrapMixin from utilities.forms import BootstrapMixin
@ -31,6 +31,7 @@ class ProviderImportForm(NetBoxModelImportForm):
class ProviderAccountImportForm(NetBoxModelImportForm): class ProviderAccountImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField( provider = CSVModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned provider') help_text=_('Assigned provider')
@ -45,6 +46,7 @@ class ProviderAccountImportForm(NetBoxModelImportForm):
class ProviderNetworkImportForm(NetBoxModelImportForm): class ProviderNetworkImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField( provider = CSVModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned provider') help_text=_('Assigned provider')
@ -67,26 +69,31 @@ class CircuitTypeImportForm(NetBoxModelImportForm):
class CircuitImportForm(NetBoxModelImportForm): class CircuitImportForm(NetBoxModelImportForm):
provider = CSVModelChoiceField( provider = CSVModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned provider') help_text=_('Assigned provider')
) )
provider_account = CSVModelChoiceField( provider_account = CSVModelChoiceField(
label=_('Provider account'),
queryset=ProviderAccount.objects.all(), queryset=ProviderAccount.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned provider account'), help_text=_('Assigned provider account'),
required=False required=False
) )
type = CSVModelChoiceField( type = CSVModelChoiceField(
label=_('Type'),
queryset=CircuitType.objects.all(), queryset=CircuitType.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Type of circuit') help_text=_('Type of circuit')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=CircuitStatusChoices, choices=CircuitStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -103,11 +110,13 @@ class CircuitImportForm(NetBoxModelImportForm):
class CircuitTerminationImportForm(BootstrapMixin, forms.ModelForm): class CircuitTerminationImportForm(BootstrapMixin, forms.ModelForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False
) )
provider_network = CSVModelChoiceField( provider_network = CSVModelChoiceField(
label=_('Provider network'),
queryset=ProviderNetwork.objects.all(), queryset=ProviderNetwork.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False

View File

@ -23,9 +23,9 @@ class ProviderFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Provider model = Provider
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('ASN', ('asn',)), (_('ASN'), ('asn',)),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -62,7 +62,7 @@ class ProviderAccountFilterForm(NetBoxModelFilterSetForm):
model = ProviderAccount model = ProviderAccount
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('provider_id', 'account')), (_('Attributes'), ('provider_id', 'account')),
) )
provider_id = DynamicModelMultipleChoiceField( provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
@ -70,6 +70,7 @@ class ProviderAccountFilterForm(NetBoxModelFilterSetForm):
label=_('Provider') label=_('Provider')
) )
account = forms.CharField( account = forms.CharField(
label=_('Account'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -79,7 +80,7 @@ class ProviderNetworkFilterForm(NetBoxModelFilterSetForm):
model = ProviderNetwork model = ProviderNetwork
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('provider_id', 'service_id')), (_('Attributes'), ('provider_id', 'service_id')),
) )
provider_id = DynamicModelMultipleChoiceField( provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
@ -87,6 +88,7 @@ class ProviderNetworkFilterForm(NetBoxModelFilterSetForm):
label=_('Provider') label=_('Provider')
) )
service_id = forms.CharField( service_id = forms.CharField(
label=_('Service id'),
max_length=100, max_length=100,
required=False required=False
) )
@ -102,11 +104,11 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
model = Circuit model = Circuit
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Provider', ('provider_id', 'provider_account_id', 'provider_network_id')), (_('Provider'), ('provider_id', 'provider_account_id', 'provider_network_id')),
('Attributes', ('type_id', 'status', 'install_date', 'termination_date', 'commit_rate')), (_('Attributes'), ('type_id', 'status', 'install_date', 'termination_date', 'commit_rate')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
type_id = DynamicModelMultipleChoiceField( type_id = DynamicModelMultipleChoiceField(
queryset=CircuitType.objects.all(), queryset=CircuitType.objects.all(),
@ -135,6 +137,7 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Provider network') label=_('Provider network')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=CircuitStatusChoices, choices=CircuitStatusChoices,
required=False required=False
) )
@ -158,10 +161,12 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Site') label=_('Site')
) )
install_date = forms.DateField( install_date = forms.DateField(
label=_('Install date'),
required=False, required=False,
widget=DatePicker widget=DatePicker
) )
termination_date = forms.DateField( termination_date = forms.DateField(
label=_('Termination date'),
required=False, required=False,
widget=DatePicker widget=DatePicker
) )

View File

@ -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.choices import CircuitCommitRateChoices, CircuitTerminationPortSpeedChoices
from circuits.models import * from circuits.models import *
@ -29,7 +29,7 @@ class ProviderForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Provider', ('name', 'slug', 'asns', 'description', 'tags')), (_('Provider'), ('name', 'slug', 'asns', 'description', 'tags')),
) )
class Meta: class Meta:
@ -41,6 +41,7 @@ class ProviderForm(NetBoxModelForm):
class ProviderAccountForm(NetBoxModelForm): class ProviderAccountForm(NetBoxModelForm):
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all() queryset=Provider.objects.all()
) )
comments = CommentField() comments = CommentField()
@ -54,12 +55,13 @@ class ProviderAccountForm(NetBoxModelForm):
class ProviderNetworkForm(NetBoxModelForm): class ProviderNetworkForm(NetBoxModelForm):
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all() queryset=Provider.objects.all()
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Provider Network', ('provider', 'name', 'service_id', 'description', 'tags')), (_('Provider Network'), ('provider', 'name', 'service_id', 'description', 'tags')),
) )
class Meta: class Meta:
@ -73,7 +75,7 @@ class CircuitTypeForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Circuit Type', ( (_('Circuit Type'), (
'name', 'slug', 'description', 'tags', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -87,10 +89,12 @@ class CircuitTypeForm(NetBoxModelForm):
class CircuitForm(TenancyForm, NetBoxModelForm): class CircuitForm(TenancyForm, NetBoxModelForm):
provider = DynamicModelChoiceField( provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
selector=True selector=True
) )
provider_account = DynamicModelChoiceField( provider_account = DynamicModelChoiceField(
label=_('Provider account'),
queryset=ProviderAccount.objects.all(), queryset=ProviderAccount.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -103,9 +107,9 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Circuit', ('provider', 'provider_account', 'cid', 'type', 'status', 'description', 'tags')), (_('Circuit'), ('provider', 'provider_account', 'cid', 'type', 'status', 'description', 'tags')),
('Service Parameters', ('install_date', 'termination_date', 'commit_rate')), (_('Service Parameters'), ('install_date', 'termination_date', 'commit_rate')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -125,15 +129,18 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
class CircuitTerminationForm(NetBoxModelForm): class CircuitTerminationForm(NetBoxModelForm):
circuit = DynamicModelChoiceField( circuit = DynamicModelChoiceField(
label=_('Circuit'),
queryset=Circuit.objects.all(), queryset=Circuit.objects.all(),
selector=True selector=True
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
selector=True selector=True
) )
provider_network = DynamicModelChoiceField( provider_network = DynamicModelChoiceField(
label=_('Provider network'),
queryset=ProviderNetwork.objects.all(), queryset=ProviderNetwork.objects.all(),
required=False, required=False,
selector=True selector=True

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import DataSourceTypeChoices
from core.models import * from core.models import *
@ -15,6 +15,7 @@ __all__ = (
class DataSourceBulkEditForm(NetBoxModelBulkEditForm): class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=add_blank_choice(DataSourceTypeChoices), choices=add_blank_choice(DataSourceTypeChoices),
required=False, required=False,
initial='' initial=''
@ -25,16 +26,17 @@ class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
label=_('Enforce unique space') label=_('Enforce unique space')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
parameters = forms.JSONField( parameters = forms.JSONField(
label=_('Parameters'),
required=False required=False
) )
ignore_rules = forms.CharField( ignore_rules = forms.CharField(
label=_('Ignore rules'),
required=False, required=False,
widget=forms.Textarea() widget=forms.Textarea()
) )

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType 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.choices import *
from core.models import * from core.models import *
@ -23,17 +23,20 @@ class DataSourceFilterForm(NetBoxModelFilterSetForm):
model = DataSource model = DataSource
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Data Source', ('type', 'status')), (_('Data Source'), ('type', 'status')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=DataSourceTypeChoices, choices=DataSourceTypeChoices,
required=False required=False
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=DataSourceStatusChoices, choices=DataSourceStatusChoices,
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -45,7 +48,7 @@ class DataFileFilterForm(NetBoxModelFilterSetForm):
model = DataFile model = DataFile
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('File', ('source_id',)), (_('File'), ('source_id',)),
) )
source_id = DynamicModelMultipleChoiceField( source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
@ -57,8 +60,8 @@ class DataFileFilterForm(NetBoxModelFilterSetForm):
class JobFilterForm(SavedFiltersMixin, FilterForm): class JobFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Attributes', ('object_type', 'status')), (_('Attributes'), ('object_type', 'status')),
('Creation', ( (_('Creation'), (
'created__before', 'created__after', 'scheduled__before', 'scheduled__after', 'started__before', 'created__before', 'created__after', 'scheduled__before', 'scheduled__after', 'started__before',
'started__after', 'completed__before', 'completed__after', 'user', 'started__after', 'completed__before', 'completed__after', 'user',
)), )),
@ -69,38 +72,47 @@ class JobFilterForm(SavedFiltersMixin, FilterForm):
required=False, required=False,
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=JobStatusChoices, choices=JobStatusChoices,
required=False required=False
) )
created__after = forms.DateTimeField( created__after = forms.DateTimeField(
label=_('Created after'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
created__before = forms.DateTimeField( created__before = forms.DateTimeField(
label=_('Created before'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
scheduled__after = forms.DateTimeField( scheduled__after = forms.DateTimeField(
label=_('Scheduled after'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
scheduled__before = forms.DateTimeField( scheduled__before = forms.DateTimeField(
label=_('Scheduled before'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
started__after = forms.DateTimeField( started__after = forms.DateTimeField(
label=_('Started after'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
started__before = forms.DateTimeField( started__before = forms.DateTimeField(
label=_('Started before'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
completed__after = forms.DateTimeField( completed__after = forms.DateTimeField(
label=_('Completed after'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )
completed__before = forms.DateTimeField( completed__before = forms.DateTimeField(
label=_('Completed before'),
required=False, required=False,
widget=DateTimePicker() widget=DateTimePicker()
) )

View File

@ -1,5 +1,5 @@
from django import forms 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 core.models import DataFile, DataSource
from utilities.forms.fields import DynamicModelChoiceField from utilities.forms.fields import DynamicModelChoiceField

View File

@ -1,6 +1,7 @@
import copy import copy
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
from core.forms.mixins import SyncedDataMixin from core.forms.mixins import SyncedDataMixin
from core.models import * from core.models import *
@ -38,11 +39,11 @@ class DataSourceForm(NetBoxModelForm):
@property @property
def fieldsets(self): def fieldsets(self):
fieldsets = [ 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: if self.backend_fields:
fieldsets.append( fieldsets.append(
('Backend Parameters', self.backend_fields) (_('Backend Parameters'), self.backend_fields)
) )
return fieldsets return fieldsets
@ -79,8 +80,8 @@ class ManagedFileForm(SyncedDataMixin, NetBoxModelForm):
) )
fieldsets = ( fieldsets = (
('File Upload', ('upload_file',)), (_('File Upload'), ('upload_file',)),
('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')), (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
) )
class Meta: class Meta:

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from dcim.models import * 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.forms import CustomFieldsMixin
from extras.models import Tag from extras.models import Tag
from utilities.forms import BootstrapMixin, form_from_model from utilities.forms import BootstrapMixin, form_from_model
@ -32,10 +32,12 @@ class DeviceBulkAddComponentForm(BootstrapMixin, CustomFieldsMixin, ComponentCre
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=100, max_length=100,
required=False required=False
) )
tags = DynamicModelMultipleChoiceField( tags = DynamicModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False
) )

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms.array import SimpleArrayField from django.contrib.postgres.forms.array import SimpleArrayField
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.utils.safestring import mark_safe 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.choices import *
from dcim.constants import * from dcim.constants import *
@ -56,6 +56,7 @@ __all__ = (
class RegionImportForm(NetBoxModelImportForm): class RegionImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -69,6 +70,7 @@ class RegionImportForm(NetBoxModelImportForm):
class SiteGroupImportForm(NetBoxModelImportForm): class SiteGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -82,22 +84,26 @@ class SiteGroupImportForm(NetBoxModelImportForm):
class SiteImportForm(NetBoxModelImportForm): class SiteImportForm(NetBoxModelImportForm):
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=SiteStatusChoices, choices=SiteStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
region = CSVModelChoiceField( region = CSVModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned region') help_text=_('Assigned region')
) )
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned group') help_text=_('Assigned group')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -119,11 +125,13 @@ class SiteImportForm(NetBoxModelImportForm):
class LocationImportForm(NetBoxModelImportForm): class LocationImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned site') help_text=_('Assigned site')
) )
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -133,10 +141,12 @@ class LocationImportForm(NetBoxModelImportForm):
} }
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=LocationStatusChoices, choices=LocationStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -161,45 +171,54 @@ class RackRoleImportForm(NetBoxModelImportForm):
class RackImportForm(NetBoxModelImportForm): class RackImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name' to_field_name='name'
) )
location = CSVModelChoiceField( location = CSVModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
to_field_name='name' to_field_name='name'
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Name of assigned tenant') help_text=_('Name of assigned tenant')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=RackStatusChoices, choices=RackStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=RackRole.objects.all(), queryset=RackRole.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Name of assigned role') help_text=_('Name of assigned role')
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=RackTypeChoices, choices=RackTypeChoices,
required=False, required=False,
help_text=_('Rack type') help_text=_('Rack type')
) )
width = forms.ChoiceField( width = forms.ChoiceField(
label=_('Width'),
choices=RackWidthChoices, choices=RackWidthChoices,
help_text=_('Rail-to-rail width (in inches)') help_text=_('Rail-to-rail width (in inches)')
) )
outer_unit = CSVChoiceField( outer_unit = CSVChoiceField(
label=_('Outer unit'),
choices=RackDimensionUnitChoices, choices=RackDimensionUnitChoices,
required=False, required=False,
help_text=_('Unit for outer dimensions') help_text=_('Unit for outer dimensions')
) )
weight_unit = CSVChoiceField( weight_unit = CSVChoiceField(
label=_('Weight unit'),
choices=WeightUnitChoices, choices=WeightUnitChoices,
required=False, required=False,
help_text=_('Unit for rack weights') help_text=_('Unit for rack weights')
@ -225,27 +244,32 @@ class RackImportForm(NetBoxModelImportForm):
class RackReservationImportForm(NetBoxModelImportForm): class RackReservationImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Parent site') help_text=_('Parent site')
) )
location = CSVModelChoiceField( location = CSVModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_("Rack's location (if any)") help_text=_("Rack's location (if any)")
) )
rack = CSVModelChoiceField( rack = CSVModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Rack') help_text=_('Rack')
) )
units = SimpleArrayField( units = SimpleArrayField(
label=_('Units'),
base_field=forms.IntegerField(), base_field=forms.IntegerField(),
required=True, required=True,
help_text=_('Comma-separated list of individual unit numbers') help_text=_('Comma-separated list of individual unit numbers')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -282,21 +306,25 @@ class ManufacturerImportForm(NetBoxModelImportForm):
class DeviceTypeImportForm(NetBoxModelImportForm): class DeviceTypeImportForm(NetBoxModelImportForm):
manufacturer = forms.ModelChoiceField( manufacturer = forms.ModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('The manufacturer which produces this device type') help_text=_('The manufacturer which produces this device type')
) )
default_platform = forms.ModelChoiceField( default_platform = forms.ModelChoiceField(
label=_('Default platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('The default platform for devices of this type (optional)') help_text=_('The default platform for devices of this type (optional)')
) )
weight = forms.DecimalField( weight = forms.DecimalField(
label=_('Weight'),
required=False, required=False,
help_text=_('Device weight'), help_text=_('Device weight'),
) )
weight_unit = CSVChoiceField( weight_unit = CSVChoiceField(
label=_('Weight unit'),
choices=WeightUnitChoices, choices=WeightUnitChoices,
required=False, required=False,
help_text=_('Unit for device weight') help_text=_('Unit for device weight')
@ -312,14 +340,17 @@ class DeviceTypeImportForm(NetBoxModelImportForm):
class ModuleTypeImportForm(NetBoxModelImportForm): class ModuleTypeImportForm(NetBoxModelImportForm):
manufacturer = forms.ModelChoiceField( manufacturer = forms.ModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='name' to_field_name='name'
) )
weight = forms.DecimalField( weight = forms.DecimalField(
label=_('Weight'),
required=False, required=False,
help_text=_('Module weight'), help_text=_('Module weight'),
) )
weight_unit = CSVChoiceField( weight_unit = CSVChoiceField(
label=_('Weight unit'),
choices=WeightUnitChoices, choices=WeightUnitChoices,
required=False, required=False,
help_text=_('Unit for module weight') help_text=_('Unit for module weight')
@ -332,6 +363,7 @@ class ModuleTypeImportForm(NetBoxModelImportForm):
class DeviceRoleImportForm(NetBoxModelImportForm): class DeviceRoleImportForm(NetBoxModelImportForm):
config_template = CSVModelChoiceField( config_template = CSVModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -350,12 +382,14 @@ class DeviceRoleImportForm(NetBoxModelImportForm):
class PlatformImportForm(NetBoxModelImportForm): class PlatformImportForm(NetBoxModelImportForm):
slug = SlugField() slug = SlugField()
manufacturer = CSVModelChoiceField( manufacturer = CSVModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Limit platform assignments to this manufacturer') help_text=_('Limit platform assignments to this manufacturer')
) )
config_template = CSVModelChoiceField( config_template = CSVModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -371,43 +405,51 @@ class PlatformImportForm(NetBoxModelImportForm):
class BaseDeviceImportForm(NetBoxModelImportForm): class BaseDeviceImportForm(NetBoxModelImportForm):
device_role = CSVModelChoiceField( device_role = CSVModelChoiceField(
label=_('Device role'),
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned role') help_text=_('Assigned role')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
manufacturer = CSVModelChoiceField( manufacturer = CSVModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Device type manufacturer') help_text=_('Device type manufacturer')
) )
device_type = CSVModelChoiceField( device_type = CSVModelChoiceField(
label=_('Device type'),
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
to_field_name='model', to_field_name='model',
help_text=_('Device type model') help_text=_('Device type model')
) )
platform = CSVModelChoiceField( platform = CSVModelChoiceField(
label=_('Platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned platform') help_text=_('Assigned platform')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=DeviceStatusChoices, choices=DeviceStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
virtual_chassis = CSVModelChoiceField( virtual_chassis = CSVModelChoiceField(
label=_('Virtual chassis'),
queryset=VirtualChassis.objects.all(), queryset=VirtualChassis.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Virtual chassis') help_text=_('Virtual chassis')
) )
cluster = CSVModelChoiceField( cluster = CSVModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -430,45 +472,53 @@ class BaseDeviceImportForm(NetBoxModelImportForm):
class DeviceImportForm(BaseDeviceImportForm): class DeviceImportForm(BaseDeviceImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned site') help_text=_('Assigned site')
) )
location = CSVModelChoiceField( location = CSVModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_("Assigned location (if any)") help_text=_("Assigned location (if any)")
) )
rack = CSVModelChoiceField( rack = CSVModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_("Assigned rack (if any)") help_text=_("Assigned rack (if any)")
) )
face = CSVChoiceField( face = CSVChoiceField(
label=_('Face'),
choices=DeviceFaceChoices, choices=DeviceFaceChoices,
required=False, required=False,
help_text=_('Mounted rack face') help_text=_('Mounted rack face')
) )
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Parent device (for child devices)') help_text=_('Parent device (for child devices)')
) )
device_bay = CSVModelChoiceField( device_bay = CSVModelChoiceField(
label=_('Device bay'),
queryset=DeviceBay.objects.all(), queryset=DeviceBay.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Device bay in which this device is installed (for child devices)') help_text=_('Device bay in which this device is installed (for child devices)')
) )
airflow = CSVChoiceField( airflow = CSVChoiceField(
label=_('Airflow'),
choices=DeviceAirflowChoices, choices=DeviceAirflowChoices,
required=False, required=False,
help_text=_('Airflow direction') help_text=_('Airflow direction')
) )
config_template = CSVModelChoiceField( config_template = CSVModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -523,29 +573,35 @@ class DeviceImportForm(BaseDeviceImportForm):
class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm): class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('The device in which this module is installed') help_text=_('The device in which this module is installed')
) )
module_bay = CSVModelChoiceField( module_bay = CSVModelChoiceField(
label=_('Module bay'),
queryset=ModuleBay.objects.all(), queryset=ModuleBay.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('The module bay in which this module is installed') help_text=_('The module bay in which this module is installed')
) )
module_type = CSVModelChoiceField( module_type = CSVModelChoiceField(
label=_('Module type'),
queryset=ModuleType.objects.all(), queryset=ModuleType.objects.all(),
to_field_name='model', to_field_name='model',
help_text=_('The type of module') help_text=_('The type of module')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=ModuleStatusChoices, choices=ModuleStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
replicate_components = forms.BooleanField( replicate_components = forms.BooleanField(
label=_('Replicate components'),
required=False, required=False,
help_text=_('Automatically populate components associated with this module type (enabled by default)') help_text=_('Automatically populate components associated with this module type (enabled by default)')
) )
adopt_components = forms.BooleanField( adopt_components = forms.BooleanField(
label=_('Adopt components'),
required=False, required=False,
help_text=_('Adopt already existing components') help_text=_('Adopt already existing components')
) )
@ -579,15 +635,18 @@ class ModuleImportForm(ModuleCommonForm, NetBoxModelImportForm):
class ConsolePortImportForm(NetBoxModelImportForm): class ConsolePortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
required=False, required=False,
help_text=_('Port type') help_text=_('Port type')
) )
speed = CSVTypedChoiceField( speed = CSVTypedChoiceField(
label=_('Speed'),
choices=ConsolePortSpeedChoices, choices=ConsolePortSpeedChoices,
coerce=int, coerce=int,
empty_value=None, empty_value=None,
@ -602,15 +661,18 @@ class ConsolePortImportForm(NetBoxModelImportForm):
class ConsoleServerPortImportForm(NetBoxModelImportForm): class ConsoleServerPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
required=False, required=False,
help_text=_('Port type') help_text=_('Port type')
) )
speed = CSVTypedChoiceField( speed = CSVTypedChoiceField(
label=_('Speed'),
choices=ConsolePortSpeedChoices, choices=ConsolePortSpeedChoices,
coerce=int, coerce=int,
empty_value=None, empty_value=None,
@ -625,10 +687,12 @@ class ConsoleServerPortImportForm(NetBoxModelImportForm):
class PowerPortImportForm(NetBoxModelImportForm): class PowerPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=PowerPortTypeChoices, choices=PowerPortTypeChoices,
required=False, required=False,
help_text=_('Port type') help_text=_('Port type')
@ -643,21 +707,25 @@ class PowerPortImportForm(NetBoxModelImportForm):
class PowerOutletImportForm(NetBoxModelImportForm): class PowerOutletImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=PowerOutletTypeChoices, choices=PowerOutletTypeChoices,
required=False, required=False,
help_text=_('Outlet type') help_text=_('Outlet type')
) )
power_port = CSVModelChoiceField( power_port = CSVModelChoiceField(
label=_('Power port'),
queryset=PowerPort.objects.all(), queryset=PowerPort.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Local power port which feeds this outlet') help_text=_('Local power port which feeds this outlet')
) )
feed_leg = CSVChoiceField( feed_leg = CSVChoiceField(
label=_('Feed lag'),
choices=PowerOutletFeedLegChoices, choices=PowerOutletFeedLegChoices,
required=False, required=False,
help_text=_('Electrical phase (for three-phase circuits)') help_text=_('Electrical phase (for three-phase circuits)')
@ -692,63 +760,75 @@ class PowerOutletImportForm(NetBoxModelImportForm):
class InterfaceImportForm(NetBoxModelImportForm): class InterfaceImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=Interface.objects.all(), queryset=Interface.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent interface') help_text=_('Parent interface')
) )
bridge = CSVModelChoiceField( bridge = CSVModelChoiceField(
label=_('Bridge'),
queryset=Interface.objects.all(), queryset=Interface.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Bridged interface') help_text=_('Bridged interface')
) )
lag = CSVModelChoiceField( lag = CSVModelChoiceField(
label=_('Lag'),
queryset=Interface.objects.all(), queryset=Interface.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent LAG interface') help_text=_('Parent LAG interface')
) )
vdcs = CSVModelMultipleChoiceField( vdcs = CSVModelMultipleChoiceField(
label=_('Vdcs'),
queryset=VirtualDeviceContext.objects.all(), queryset=VirtualDeviceContext.objects.all(),
required=False, required=False,
to_field_name='name', 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( type = CSVChoiceField(
label=_('Type'),
choices=InterfaceTypeChoices, choices=InterfaceTypeChoices,
help_text=_('Physical medium') help_text=_('Physical medium')
) )
duplex = CSVChoiceField( duplex = CSVChoiceField(
label=_('Duplex'),
choices=InterfaceDuplexChoices, choices=InterfaceDuplexChoices,
required=False required=False
) )
poe_mode = CSVChoiceField( poe_mode = CSVChoiceField(
label=_('Poe mode'),
choices=InterfacePoEModeChoices, choices=InterfacePoEModeChoices,
required=False, required=False,
help_text=_('PoE mode') help_text=_('PoE mode')
) )
poe_type = CSVChoiceField( poe_type = CSVChoiceField(
label=_('Poe type'),
choices=InterfacePoETypeChoices, choices=InterfacePoETypeChoices,
required=False, required=False,
help_text=_('PoE type') help_text=_('PoE type')
) )
mode = CSVChoiceField( mode = CSVChoiceField(
label=_('Mode'),
choices=InterfaceModeChoices, choices=InterfaceModeChoices,
required=False, required=False,
help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)') help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)')
) )
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
to_field_name='rd', to_field_name='rd',
help_text=_('Assigned VRF') help_text=_('Assigned VRF')
) )
rf_role = CSVChoiceField( rf_role = CSVChoiceField(
label=_('Rf role'),
choices=WirelessRoleChoices, choices=WirelessRoleChoices,
required=False, required=False,
help_text=_('Wireless role (AP/station)') help_text=_('Wireless role (AP/station)')
@ -792,15 +872,18 @@ class InterfaceImportForm(NetBoxModelImportForm):
class FrontPortImportForm(NetBoxModelImportForm): class FrontPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
rear_port = CSVModelChoiceField( rear_port = CSVModelChoiceField(
label=_('Rear port'),
queryset=RearPort.objects.all(), queryset=RearPort.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Corresponding rear port') help_text=_('Corresponding rear port')
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=PortTypeChoices, choices=PortTypeChoices,
help_text=_('Physical medium classification') help_text=_('Physical medium classification')
) )
@ -837,10 +920,12 @@ class FrontPortImportForm(NetBoxModelImportForm):
class RearPortImportForm(NetBoxModelImportForm): class RearPortImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
help_text=_('Physical medium classification'), help_text=_('Physical medium classification'),
choices=PortTypeChoices, choices=PortTypeChoices,
) )
@ -852,6 +937,7 @@ class RearPortImportForm(NetBoxModelImportForm):
class ModuleBayImportForm(NetBoxModelImportForm): class ModuleBayImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
@ -863,10 +949,12 @@ class ModuleBayImportForm(NetBoxModelImportForm):
class DeviceBayImportForm(NetBoxModelImportForm): class DeviceBayImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
installed_device = CSVModelChoiceField( installed_device = CSVModelChoiceField(
label=_('Installed device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -909,32 +997,38 @@ class DeviceBayImportForm(NetBoxModelImportForm):
class InventoryItemImportForm(NetBoxModelImportForm): class InventoryItemImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name' to_field_name='name'
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=InventoryItemRole.objects.all(), queryset=InventoryItemRole.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False
) )
manufacturer = CSVModelChoiceField( manufacturer = CSVModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False
) )
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Parent inventory item') help_text=_('Parent inventory item')
) )
component_type = CSVContentTypeField( component_type = CSVContentTypeField(
label=_('Component type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=MODULAR_COMPONENT_MODELS, limit_choices_to=MODULAR_COMPONENT_MODELS,
required=False, required=False,
help_text=_('Component Type') help_text=_('Component Type')
) )
component_name = forms.CharField( component_name = forms.CharField(
label=_('Compnent name'),
required=False, required=False,
help_text=_('Component Name') help_text=_('Component Name')
) )
@ -1002,52 +1096,62 @@ class InventoryItemRoleImportForm(NetBoxModelImportForm):
class CableImportForm(NetBoxModelImportForm): class CableImportForm(NetBoxModelImportForm):
# Termination A # Termination A
side_a_device = CSVModelChoiceField( side_a_device = CSVModelChoiceField(
label=_('Side a device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Side A device') help_text=_('Side A device')
) )
side_a_type = CSVContentTypeField( side_a_type = CSVContentTypeField(
label=_('Side a type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS, limit_choices_to=CABLE_TERMINATION_MODELS,
help_text=_('Side A type') help_text=_('Side A type')
) )
side_a_name = forms.CharField( side_a_name = forms.CharField(
label=_('Side a name'),
help_text=_('Side A component name') help_text=_('Side A component name')
) )
# Termination B # Termination B
side_b_device = CSVModelChoiceField( side_b_device = CSVModelChoiceField(
label=_('Side b device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Side B device') help_text=_('Side B device')
) )
side_b_type = CSVContentTypeField( side_b_type = CSVContentTypeField(
label=_('Side b type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS, limit_choices_to=CABLE_TERMINATION_MODELS,
help_text=_('Side B type') help_text=_('Side B type')
) )
side_b_name = forms.CharField( side_b_name = forms.CharField(
label=_('Side b name'),
help_text=_('Side B component name') help_text=_('Side B component name')
) )
# Cable attributes # Cable attributes
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=LinkStatusChoices, choices=LinkStatusChoices,
required=False, required=False,
help_text=_('Connection status') help_text=_('Connection status')
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=CableTypeChoices, choices=CableTypeChoices,
required=False, required=False,
help_text=_('Physical medium classification') help_text=_('Physical medium classification')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
length_unit = CSVChoiceField( length_unit = CSVChoiceField(
label=_('Length unit'),
choices=CableLengthUnitChoices, choices=CableLengthUnitChoices,
required=False, required=False,
help_text=_('Length unit') help_text=_('Length unit')
@ -1110,6 +1214,7 @@ class CableImportForm(NetBoxModelImportForm):
class VirtualChassisImportForm(NetBoxModelImportForm): class VirtualChassisImportForm(NetBoxModelImportForm):
master = CSVModelChoiceField( master = CSVModelChoiceField(
label=_('Master'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -1127,11 +1232,13 @@ class VirtualChassisImportForm(NetBoxModelImportForm):
class PowerPanelImportForm(NetBoxModelImportForm): class PowerPanelImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Name of parent site') help_text=_('Name of parent site')
) )
location = CSVModelChoiceField( location = CSVModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
to_field_name='name' to_field_name='name'
@ -1153,22 +1260,26 @@ class PowerPanelImportForm(NetBoxModelImportForm):
class PowerFeedImportForm(NetBoxModelImportForm): class PowerFeedImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned site') help_text=_('Assigned site')
) )
power_panel = CSVModelChoiceField( power_panel = CSVModelChoiceField(
label=_('Power panel'),
queryset=PowerPanel.objects.all(), queryset=PowerPanel.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Upstream power panel') help_text=_('Upstream power panel')
) )
location = CSVModelChoiceField( location = CSVModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_("Rack's location (if any)") help_text=_("Rack's location (if any)")
) )
rack = CSVModelChoiceField( rack = CSVModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -1181,18 +1292,22 @@ class PowerFeedImportForm(NetBoxModelImportForm):
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=PowerFeedStatusChoices, choices=PowerFeedStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=PowerFeedTypeChoices, choices=PowerFeedTypeChoices,
help_text=_('Primary or redundant') help_text=_('Primary or redundant')
) )
supply = CSVChoiceField( supply = CSVChoiceField(
label=_('Supply'),
choices=PowerFeedSupplyChoices, choices=PowerFeedSupplyChoices,
help_text=_('Supply type (AC/DC)') help_text=_('Supply type (AC/DC)')
) )
phase = CSVChoiceField( phase = CSVChoiceField(
label=_('Phase'),
choices=PowerFeedPhaseChoices, choices=PowerFeedPhaseChoices,
help_text=_('Single or three-phase') help_text=_('Single or three-phase')
) )
@ -1228,11 +1343,13 @@ class PowerFeedImportForm(NetBoxModelImportForm):
class VirtualDeviceContextImportForm(NetBoxModelImportForm): class VirtualDeviceContextImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
help_text='Assigned role' help_text='Assigned role'
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import *
from dcim.constants import * from dcim.constants import *
@ -47,7 +47,7 @@ class InterfaceCommonForm(forms.Form):
# Untagged interfaces cannot be assigned tagged VLANs # Untagged interfaces cannot be assigned tagged VLANs
if self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and tagged_vlans: if self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and tagged_vlans:
raise forms.ValidationError({ 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 # Remove all tagged VLAN assignments from "tagged all" interfaces
@ -61,8 +61,10 @@ class InterfaceCommonForm(forms.Form):
if invalid_vlans: if invalid_vlans:
raise forms.ValidationError({ raise forms.ValidationError({
'tagged_vlans': f"The tagged VLANs ({', '.join(invalid_vlans)}) must belong to the same site as " 'tagged_vlans': _(
f"the interface's parent device/VM, or they must be global" "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 # Installing modules with placeholders require that the bay has a position value
if MODULE_TOKEN in template.name and not module_bay.position: if MODULE_TOKEN in template.name and not module_bay.position:
raise forms.ValidationError( 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) 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 # It is not possible to adopt components already belonging to a module
if adopt_components and existing_item and existing_item.module: if adopt_components and existing_item and existing_item.module:
raise forms.ValidationError( raise forms.ValidationError(
f"Cannot adopt {template.component_model.__name__} '{resolved_name}' as it already belongs " _("Cannot adopt {name} '{resolved_name}' as it already belongs to a module").format(
f"to a module" name=template.component_model.__name__,
resolved_name=resolved_name
)
) )
# If we are not adopting components we error if the component exists # If we are not adopting components we error if the component exists
if not adopt_components and resolved_name in installed_components: if not adopt_components and resolved_name in installed_components:
raise forms.ValidationError( 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
)
) )

View File

@ -1,5 +1,5 @@
from django import forms 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 circuits.models import Circuit, CircuitTermination
from dcim.models import * from dcim.models import *

View File

@ -1,6 +1,6 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model 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.choices import *
from dcim.constants import * from dcim.constants import *
@ -56,9 +56,11 @@ __all__ = (
class DeviceComponentFilterForm(NetBoxModelFilterSetForm): class DeviceComponentFilterForm(NetBoxModelFilterSetForm):
name = forms.CharField( name = forms.CharField(
label=_('Name'),
required=False required=False
) )
label = forms.CharField( label = forms.CharField(
label=_('Label'),
required=False required=False
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
@ -130,7 +132,7 @@ class RegionFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Region model = Region
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag', 'parent_id')), (None, ('q', 'filter_id', 'tag', 'parent_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')) (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
) )
parent_id = DynamicModelMultipleChoiceField( parent_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -144,7 +146,7 @@ class SiteGroupFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = SiteGroup model = SiteGroup
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag', 'parent_id')), (None, ('q', 'filter_id', 'tag', 'parent_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')) (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
) )
parent_id = DynamicModelMultipleChoiceField( parent_id = DynamicModelMultipleChoiceField(
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
@ -158,11 +160,12 @@ class SiteFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
model = Site model = Site
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('status', 'region_id', 'group_id', 'asn_id')), (_('Attributes'), ('status', 'region_id', 'group_id', 'asn_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=SiteStatusChoices, choices=SiteStatusChoices,
required=False required=False
) )
@ -188,9 +191,9 @@ class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelF
model = Location model = Location
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('region_id', 'site_group_id', 'site_id', 'parent_id', 'status')), (_('Attributes'), ('region_id', 'site_group_id', 'site_id', 'parent_id', 'status')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -221,6 +224,7 @@ class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelF
label=_('Parent') label=_('Parent')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=LocationStatusChoices, choices=LocationStatusChoices,
required=False required=False
) )
@ -236,12 +240,12 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
model = Rack model = Rack
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
('Function', ('status', 'role_id')), (_('Function'), ('status', 'role_id')),
('Hardware', ('type', 'width', 'serial', 'asset_tag')), (_('Hardware'), ('type', 'width', 'serial', 'asset_tag')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
('Weight', ('weight', 'max_weight', 'weight_unit')), (_('Weight'), ('weight', 'max_weight', 'weight_unit')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -271,14 +275,17 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
label=_('Location') label=_('Location')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=RackStatusChoices, choices=RackStatusChoices,
required=False required=False
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=RackTypeChoices, choices=RackTypeChoices,
required=False required=False
) )
width = forms.MultipleChoiceField( width = forms.MultipleChoiceField(
label=_('Width'),
choices=RackWidthChoices, choices=RackWidthChoices,
required=False required=False
) )
@ -289,21 +296,26 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
label=_('Role') label=_('Role')
) )
serial = forms.CharField( serial = forms.CharField(
label=_('Serial'),
required=False required=False
) )
asset_tag = forms.CharField( asset_tag = forms.CharField(
label=_('Asset tag'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
weight = forms.DecimalField( weight = forms.DecimalField(
label=_('Weight'),
required=False, required=False,
min_value=1 min_value=1
) )
max_weight = forms.IntegerField( max_weight = forms.IntegerField(
label=_('Max weight'),
required=False, required=False,
min_value=1 min_value=1
) )
weight_unit = forms.ChoiceField( weight_unit = forms.ChoiceField(
label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices), choices=add_blank_choice(WeightUnitChoices),
required=False required=False
) )
@ -312,12 +324,12 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
class RackElevationFilterForm(RackFilterForm): class RackElevationFilterForm(RackFilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'id')),
('Function', ('status', 'role_id')), (_('Function'), ('status', 'role_id')),
('Hardware', ('type', 'width', 'serial', 'asset_tag')), (_('Hardware'), ('type', 'width', 'serial', 'asset_tag')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
('Weight', ('weight', 'max_weight', 'weight_unit')), (_('Weight'), ('weight', 'max_weight', 'weight_unit')),
) )
id = DynamicModelMultipleChoiceField( id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
@ -334,9 +346,9 @@ class RackReservationFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = RackReservation model = RackReservation
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('User', ('user_id',)), (_('User'), ('user_id',)),
('Rack', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Rack'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -390,7 +402,7 @@ class ManufacturerFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = Manufacturer model = Manufacturer
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Contacts', ('contact', 'contact_role', 'contact_group')) (_('Contacts'), ('contact', 'contact_role', 'contact_group'))
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -399,13 +411,13 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
model = DeviceType model = DeviceType
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Hardware', ('manufacturer_id', 'default_platform_id', 'part_number', 'subdevice_role', 'airflow')), (_('Hardware'), ('manufacturer_id', 'default_platform_id', 'part_number', 'subdevice_role', 'airflow')),
('Images', ('has_front_image', 'has_rear_image')), (_('Images'), ('has_front_image', 'has_rear_image')),
('Components', ( (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
'pass_through_ports', 'device_bays', 'module_bays', 'inventory_items', 'pass_through_ports', 'device_bays', 'module_bays', 'inventory_items',
)), )),
('Weight', ('weight', 'weight_unit')), (_('Weight'), ('weight', 'weight_unit')),
) )
manufacturer_id = DynamicModelMultipleChoiceField( manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
@ -418,98 +430,103 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
label=_('Default platform') label=_('Default platform')
) )
part_number = forms.CharField( part_number = forms.CharField(
label=_('Part number'),
required=False required=False
) )
subdevice_role = forms.MultipleChoiceField( subdevice_role = forms.MultipleChoiceField(
label=_('Subdevice role'),
choices=add_blank_choice(SubdeviceRoleChoices), choices=add_blank_choice(SubdeviceRoleChoices),
required=False required=False
) )
airflow = forms.MultipleChoiceField( airflow = forms.MultipleChoiceField(
label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices), choices=add_blank_choice(DeviceAirflowChoices),
required=False required=False
) )
has_front_image = forms.NullBooleanField( has_front_image = forms.NullBooleanField(
required=False, required=False,
label='Has a front image', label=_('Has a front image'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
has_rear_image = forms.NullBooleanField( has_rear_image = forms.NullBooleanField(
required=False, required=False,
label='Has a rear image', label=_('Has a rear image'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
console_ports = forms.NullBooleanField( console_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console ports', label=_('Has console ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
console_server_ports = forms.NullBooleanField( console_server_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console server ports', label=_('Has console server ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_ports = forms.NullBooleanField( power_ports = forms.NullBooleanField(
required=False, required=False,
label='Has power ports', label=_('Has power ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_outlets = forms.NullBooleanField( power_outlets = forms.NullBooleanField(
required=False, required=False,
label='Has power outlets', label=_('Has power outlets'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
interfaces = forms.NullBooleanField( interfaces = forms.NullBooleanField(
required=False, required=False,
label='Has interfaces', label=_('Has interfaces'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
pass_through_ports = forms.NullBooleanField( pass_through_ports = forms.NullBooleanField(
required=False, required=False,
label='Has pass-through ports', label=_('Has pass-through ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
device_bays = forms.NullBooleanField( device_bays = forms.NullBooleanField(
required=False, required=False,
label='Has device bays', label=_('Has device bays'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
module_bays = forms.NullBooleanField( module_bays = forms.NullBooleanField(
required=False, required=False,
label='Has module bays', label=_('Has module bays'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
inventory_items = forms.NullBooleanField( inventory_items = forms.NullBooleanField(
required=False, required=False,
label='Has inventory items', label=_('Has inventory items'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
tag = TagFilterField(model) tag = TagFilterField(model)
weight = forms.DecimalField( weight = forms.DecimalField(
label=_('Weight'),
required=False required=False
) )
weight_unit = forms.ChoiceField( weight_unit = forms.ChoiceField(
label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices), choices=add_blank_choice(WeightUnitChoices),
required=False required=False
) )
@ -519,12 +536,12 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
model = ModuleType model = ModuleType
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Hardware', ('manufacturer_id', 'part_number')), (_('Hardware'), ('manufacturer_id', 'part_number')),
('Components', ( (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces',
'pass_through_ports', 'pass_through_ports',
)), )),
('Weight', ('weight', 'weight_unit')), (_('Weight'), ('weight', 'weight_unit')),
) )
manufacturer_id = DynamicModelMultipleChoiceField( manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
@ -533,55 +550,58 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
fetch_trigger='open' fetch_trigger='open'
) )
part_number = forms.CharField( part_number = forms.CharField(
label=_('Part number'),
required=False required=False
) )
console_ports = forms.NullBooleanField( console_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console ports', label=_('Has console ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
console_server_ports = forms.NullBooleanField( console_server_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console server ports', label=_('Has console server ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_ports = forms.NullBooleanField( power_ports = forms.NullBooleanField(
required=False, required=False,
label='Has power ports', label=_('Has power ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_outlets = forms.NullBooleanField( power_outlets = forms.NullBooleanField(
required=False, required=False,
label='Has power outlets', label=_('Has power outlets'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
interfaces = forms.NullBooleanField( interfaces = forms.NullBooleanField(
required=False, required=False,
label='Has interfaces', label=_('Has interfaces'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
pass_through_ports = forms.NullBooleanField( pass_through_ports = forms.NullBooleanField(
required=False, required=False,
label='Has pass-through ports', label=_('Has pass-through ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
tag = TagFilterField(model) tag = TagFilterField(model)
weight = forms.DecimalField( weight = forms.DecimalField(
label=_('Weight'),
required=False required=False
) )
weight_unit = forms.ChoiceField( weight_unit = forms.ChoiceField(
label=_('Weight unit'),
choices=add_blank_choice(WeightUnitChoices), choices=add_blank_choice(WeightUnitChoices),
required=False required=False
) )
@ -621,15 +641,17 @@ class DeviceFilterForm(
model = Device model = Device
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Operation', ('status', 'role_id', 'airflow', 'serial', 'asset_tag', 'mac_address')), (_('Operation'), ('status', 'role_id', 'airflow', 'serial', 'asset_tag', 'mac_address')),
('Hardware', ('manufacturer_id', 'device_type_id', 'platform_id')), (_('Hardware'), ('manufacturer_id', 'device_type_id', 'platform_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
('Components', ( (_('Components'), (
'console_ports', 'console_server_ports', 'power_ports', 'power_outlets', 'interfaces', 'pass_through_ports', '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( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -694,22 +716,26 @@ class DeviceFilterForm(
label=_('Platform') label=_('Platform')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=DeviceStatusChoices, choices=DeviceStatusChoices,
required=False required=False
) )
airflow = forms.MultipleChoiceField( airflow = forms.MultipleChoiceField(
label=_('Airflow'),
choices=add_blank_choice(DeviceAirflowChoices), choices=add_blank_choice(DeviceAirflowChoices),
required=False required=False
) )
serial = forms.CharField( serial = forms.CharField(
label=_('Serial'),
required=False required=False
) )
asset_tag = forms.CharField( asset_tag = forms.CharField(
label=_('Asset tag'),
required=False required=False
) )
mac_address = forms.CharField( mac_address = forms.CharField(
required=False, required=False,
label='MAC address' label=_('MAC address')
) )
config_template_id = DynamicModelMultipleChoiceField( config_template_id = DynamicModelMultipleChoiceField(
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
@ -718,7 +744,7 @@ class DeviceFilterForm(
) )
has_primary_ip = forms.NullBooleanField( has_primary_ip = forms.NullBooleanField(
required=False, required=False,
label='Has a primary IP', label=_('Has a primary IP'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -732,49 +758,49 @@ class DeviceFilterForm(
) )
virtual_chassis_member = forms.NullBooleanField( virtual_chassis_member = forms.NullBooleanField(
required=False, required=False,
label='Virtual chassis member', label=_('Virtual chassis member'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
console_ports = forms.NullBooleanField( console_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console ports', label=_('Has console ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
console_server_ports = forms.NullBooleanField( console_server_ports = forms.NullBooleanField(
required=False, required=False,
label='Has console server ports', label=_('Has console server ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_ports = forms.NullBooleanField( power_ports = forms.NullBooleanField(
required=False, required=False,
label='Has power ports', label=_('Has power ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
power_outlets = forms.NullBooleanField( power_outlets = forms.NullBooleanField(
required=False, required=False,
label='Has power outlets', label=_('Has power outlets'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
interfaces = forms.NullBooleanField( interfaces = forms.NullBooleanField(
required=False, required=False,
label='Has interfaces', label=_('Has interfaces'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
pass_through_ports = forms.NullBooleanField( pass_through_ports = forms.NullBooleanField(
required=False, required=False,
label='Has pass-through ports', label=_('Has pass-through ports'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -789,8 +815,8 @@ class VirtualDeviceContextFilterForm(
model = VirtualDeviceContext model = VirtualDeviceContext
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('device', 'status', 'has_primary_ip')), (_('Attributes'), ('device', 'status', 'has_primary_ip')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
device = DynamicModelMultipleChoiceField( device = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
@ -799,12 +825,13 @@ class VirtualDeviceContextFilterForm(
fetch_trigger='open' fetch_trigger='open'
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
required=False, required=False,
choices=add_blank_choice(VirtualDeviceContextStatusChoices) choices=add_blank_choice(VirtualDeviceContextStatusChoices)
) )
has_primary_ip = forms.NullBooleanField( has_primary_ip = forms.NullBooleanField(
required=False, required=False,
label='Has a primary IP', label=_('Has a primary IP'),
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -816,7 +843,7 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
model = Module model = Module
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (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( manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
@ -834,13 +861,16 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
fetch_trigger='open' fetch_trigger='open'
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=ModuleStatusChoices, choices=ModuleStatusChoices,
required=False required=False
) )
serial = forms.CharField( serial = forms.CharField(
label=_('Serial'),
required=False required=False
) )
asset_tag = forms.CharField( asset_tag = forms.CharField(
label=_('Asset tag'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -850,8 +880,8 @@ class VirtualChassisFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VirtualChassis model = VirtualChassis
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -879,9 +909,9 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Cable model = Cable
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('site_id', 'location_id', 'rack_id', 'device_id')), (_('Location'), ('site_id', 'location_id', 'rack_id', 'device_id')),
('Attributes', ('type', 'status', 'color', 'length', 'length_unit')), (_('Attributes'), ('type', 'status', 'color', 'length', 'length_unit')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -927,20 +957,25 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Device') label=_('Device')
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=add_blank_choice(CableTypeChoices), choices=add_blank_choice(CableTypeChoices),
required=False required=False
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
required=False, required=False,
choices=add_blank_choice(LinkStatusChoices) choices=add_blank_choice(LinkStatusChoices)
) )
color = ColorField( color = ColorField(
label=_('Color'),
required=False required=False
) )
length = forms.IntegerField( length = forms.IntegerField(
label=_('Length'),
required=False required=False
) )
length_unit = forms.ChoiceField( length_unit = forms.ChoiceField(
label=_('Length unit'),
choices=add_blank_choice(CableLengthUnitChoices), choices=add_blank_choice(CableLengthUnitChoices),
required=False required=False
) )
@ -951,8 +986,8 @@ class PowerPanelFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
model = PowerPanel model = PowerPanel
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -989,9 +1024,9 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = PowerFeed model = PowerFeed
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id', 'power_panel_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'power_panel_id', 'rack_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Attributes', ('status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization')), (_('Attributes'), ('status', 'type', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -1030,28 +1065,35 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Rack') label=_('Rack')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=PowerFeedStatusChoices, choices=PowerFeedStatusChoices,
required=False required=False
) )
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=add_blank_choice(PowerFeedTypeChoices), choices=add_blank_choice(PowerFeedTypeChoices),
required=False required=False
) )
supply = forms.ChoiceField( supply = forms.ChoiceField(
label=_('Supply'),
choices=add_blank_choice(PowerFeedSupplyChoices), choices=add_blank_choice(PowerFeedSupplyChoices),
required=False required=False
) )
phase = forms.ChoiceField( phase = forms.ChoiceField(
label=_('Phase'),
choices=add_blank_choice(PowerFeedPhaseChoices), choices=add_blank_choice(PowerFeedPhaseChoices),
required=False required=False
) )
voltage = forms.IntegerField( voltage = forms.IntegerField(
label=_('Voltage'),
required=False required=False
) )
amperage = forms.IntegerField( amperage = forms.IntegerField(
label=_('Amperage'),
required=False required=False
) )
max_utilization = forms.IntegerField( max_utilization = forms.IntegerField(
label=_('Max utilization'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -1063,12 +1105,14 @@ class PowerFeedFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
class CabledFilterForm(forms.Form): class CabledFilterForm(forms.Form):
cabled = forms.NullBooleanField( cabled = forms.NullBooleanField(
label=_('Cabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
occupied = forms.NullBooleanField( occupied = forms.NullBooleanField(
label=_('Occupied'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -1078,6 +1122,7 @@ class CabledFilterForm(forms.Form):
class PathEndpointFilterForm(CabledFilterForm): class PathEndpointFilterForm(CabledFilterForm):
connected = forms.NullBooleanField( connected = forms.NullBooleanField(
label=_('Connected'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -1089,16 +1134,18 @@ class ConsolePortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = ConsolePort model = ConsolePort
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type', 'speed')), (_('Attributes'), ('name', 'label', 'type', 'speed')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Connection', ('cabled', 'connected', 'occupied')), (_('Connection'), ('cabled', 'connected', 'occupied')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
required=False required=False
) )
speed = forms.MultipleChoiceField( speed = forms.MultipleChoiceField(
label=_('Speed'),
choices=ConsolePortSpeedChoices, choices=ConsolePortSpeedChoices,
required=False required=False
) )
@ -1109,16 +1156,18 @@ class ConsoleServerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterF
model = ConsoleServerPort model = ConsoleServerPort
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type', 'speed')), (_('Attributes'), ('name', 'label', 'type', 'speed')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Connection', ('cabled', 'connected', 'occupied')), (_('Connection'), ('cabled', 'connected', 'occupied')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
required=False required=False
) )
speed = forms.MultipleChoiceField( speed = forms.MultipleChoiceField(
label=_('Speed'),
choices=ConsolePortSpeedChoices, choices=ConsolePortSpeedChoices,
required=False required=False
) )
@ -1129,12 +1178,13 @@ class PowerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = PowerPort model = PowerPort
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type')), (_('Attributes'), ('name', 'label', 'type')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Connection', ('cabled', 'connected', 'occupied')), (_('Connection'), ('cabled', 'connected', 'occupied')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=PowerPortTypeChoices, choices=PowerPortTypeChoices,
required=False required=False
) )
@ -1145,12 +1195,13 @@ class PowerOutletFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = PowerOutlet model = PowerOutlet
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type')), (_('Attributes'), ('name', 'label', 'type')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Connection', ('cabled', 'connected', 'occupied')), (_('Connection'), ('cabled', 'connected', 'occupied')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=PowerOutletTypeChoices, choices=PowerOutletTypeChoices,
required=False required=False
) )
@ -1161,13 +1212,13 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
model = Interface model = Interface
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only')), (_('Attributes'), ('name', 'label', 'kind', 'type', 'speed', 'duplex', 'enabled', 'mgmt_only')),
('Addressing', ('vrf_id', 'l2vpn_id', 'mac_address', 'wwn')), (_('Addressing'), ('vrf_id', 'l2vpn_id', 'mac_address', 'wwn')),
('PoE', ('poe_mode', 'poe_type')), (_('PoE'), ('poe_mode', 'poe_type')),
('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')), (_('Wireless'), ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('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')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id', 'vdc_id')),
('Connection', ('cabled', 'connected', 'occupied')), (_('Connection'), ('cabled', 'connected', 'occupied')),
) )
vdc_id = DynamicModelMultipleChoiceField( vdc_id = DynamicModelMultipleChoiceField(
queryset=VirtualDeviceContext.objects.all(), queryset=VirtualDeviceContext.objects.all(),
@ -1178,30 +1229,36 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
label=_('Virtual Device Context') label=_('Virtual Device Context')
) )
kind = forms.MultipleChoiceField( kind = forms.MultipleChoiceField(
label=_('Kind'),
choices=InterfaceKindChoices, choices=InterfaceKindChoices,
required=False required=False
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=InterfaceTypeChoices, choices=InterfaceTypeChoices,
required=False required=False
) )
speed = forms.IntegerField( speed = forms.IntegerField(
label=_('Speed'),
required=False, required=False,
widget=NumberWithOptions( widget=NumberWithOptions(
options=InterfaceSpeedChoices options=InterfaceSpeedChoices
) )
) )
duplex = forms.MultipleChoiceField( duplex = forms.MultipleChoiceField(
label=_('Duplex'),
choices=InterfaceDuplexChoices, choices=InterfaceDuplexChoices,
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
mgmt_only = forms.NullBooleanField( mgmt_only = forms.NullBooleanField(
label=_('Mgmt only'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -1209,50 +1266,50 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
) )
mac_address = forms.CharField( mac_address = forms.CharField(
required=False, required=False,
label='MAC address' label=_('MAC address')
) )
wwn = forms.CharField( wwn = forms.CharField(
required=False, required=False,
label='WWN' label=_('WWN')
) )
poe_mode = forms.MultipleChoiceField( poe_mode = forms.MultipleChoiceField(
choices=InterfacePoEModeChoices, choices=InterfacePoEModeChoices,
required=False, required=False,
label='PoE mode' label=_('PoE mode')
) )
poe_type = forms.MultipleChoiceField( poe_type = forms.MultipleChoiceField(
choices=InterfacePoETypeChoices, choices=InterfacePoETypeChoices,
required=False, required=False,
label='PoE type' label=_('PoE type')
) )
rf_role = forms.MultipleChoiceField( rf_role = forms.MultipleChoiceField(
choices=WirelessRoleChoices, choices=WirelessRoleChoices,
required=False, required=False,
label='Wireless role' label=_('Wireless role')
) )
rf_channel = forms.MultipleChoiceField( rf_channel = forms.MultipleChoiceField(
choices=WirelessChannelChoices, choices=WirelessChannelChoices,
required=False, required=False,
label='Wireless channel' label=_('Wireless channel')
) )
rf_channel_frequency = forms.IntegerField( rf_channel_frequency = forms.IntegerField(
required=False, required=False,
label='Channel frequency (MHz)' label=_('Channel frequency (MHz)')
) )
rf_channel_width = forms.IntegerField( rf_channel_width = forms.IntegerField(
required=False, required=False,
label='Channel width (MHz)' label=_('Channel width (MHz)')
) )
tx_power = forms.IntegerField( tx_power = forms.IntegerField(
required=False, required=False,
label='Transmit power (dBm)', label=_('Transmit power (dBm)'),
min_value=0, min_value=0,
max_value=127 max_value=127
) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='VRF' label=_('VRF')
) )
l2vpn_id = DynamicModelMultipleChoiceField( l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(), queryset=L2VPN.objects.all(),
@ -1265,17 +1322,19 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
class FrontPortFilterForm(CabledFilterForm, DeviceComponentFilterForm): class FrontPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type', 'color')), (_('Attributes'), ('name', 'label', 'type', 'color')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Cable', ('cabled', 'occupied')), (_('Cable'), ('cabled', 'occupied')),
) )
model = FrontPort model = FrontPort
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=PortTypeChoices, choices=PortTypeChoices,
required=False required=False
) )
color = ColorField( color = ColorField(
label=_('Color'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -1285,16 +1344,18 @@ class RearPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
model = RearPort model = RearPort
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'type', 'color')), (_('Attributes'), ('name', 'label', 'type', 'color')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
('Cable', ('cabled', 'occupied')), (_('Cable'), ('cabled', 'occupied')),
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
label=_('Type'),
choices=PortTypeChoices, choices=PortTypeChoices,
required=False required=False
) )
color = ColorField( color = ColorField(
label=_('Color'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -1304,12 +1365,13 @@ class ModuleBayFilterForm(DeviceComponentFilterForm):
model = ModuleBay model = ModuleBay
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'position')), (_('Attributes'), ('name', 'label', 'position')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
) )
tag = TagFilterField(model) tag = TagFilterField(model)
position = forms.CharField( position = forms.CharField(
label=_('Position'),
required=False required=False
) )
@ -1318,9 +1380,9 @@ class DeviceBayFilterForm(DeviceComponentFilterForm):
model = DeviceBay model = DeviceBay
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label')), (_('Attributes'), ('name', 'label')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -1329,9 +1391,9 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
model = InventoryItem model = InventoryItem
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'label', 'role_id', 'manufacturer_id', 'serial', 'asset_tag', 'discovered')), (_('Attributes'), ('name', 'label', 'role_id', 'manufacturer_id', 'serial', 'asset_tag', 'discovered')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id')),
('Device', ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')), (_('Device'), ('device_type_id', 'device_role_id', 'device_id', 'virtual_chassis_id')),
) )
role_id = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=InventoryItemRole.objects.all(), queryset=InventoryItemRole.objects.all(),
@ -1345,12 +1407,15 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
label=_('Manufacturer') label=_('Manufacturer')
) )
serial = forms.CharField( serial = forms.CharField(
label=_('Serial'),
required=False required=False
) )
asset_tag = forms.CharField( asset_tag = forms.CharField(
label=_('Asset tag'),
required=False required=False
) )
discovered = forms.NullBooleanField( discovered = forms.NullBooleanField(
label=_('Discovered'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
__all__ = ( __all__ = (
'BaseVCMemberFormSet', 'BaseVCMemberFormSet',
@ -16,6 +17,8 @@ class BaseVCMemberFormSet(forms.BaseModelFormSet):
vc_position = form.cleaned_data.get('vc_position') vc_position = form.cleaned_data.get('vc_position')
if vc_position: if vc_position:
if vc_position in vc_position_list: 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) form.add_error('vc_position', error_msg)
vc_position_list.append(vc_position) vc_position_list.append(vc_position)

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType 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 timezone_field import TimeZoneFormField
from dcim.choices import * from dcim.choices import *
@ -70,13 +70,14 @@ __all__ = (
class RegionForm(NetBoxModelForm): class RegionForm(NetBoxModelForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Region', ( (_('Region'), (
'parent', 'name', 'slug', 'description', 'tags', 'parent', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -90,13 +91,14 @@ class RegionForm(NetBoxModelForm):
class SiteGroupForm(NetBoxModelForm): class SiteGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Site Group', ( (_('Site Group'), (
'parent', 'name', 'slug', 'description', 'tags', 'parent', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -110,10 +112,12 @@ class SiteGroupForm(NetBoxModelForm):
class SiteForm(TenancyForm, NetBoxModelForm): class SiteForm(TenancyForm, NetBoxModelForm):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False required=False
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False required=False
) )
@ -124,17 +128,18 @@ class SiteForm(TenancyForm, NetBoxModelForm):
) )
slug = SlugField() slug = SlugField()
time_zone = TimeZoneFormField( time_zone = TimeZoneFormField(
label=_('Time zone'),
choices=add_blank_choice(TimeZoneFormField().choices), choices=add_blank_choice(TimeZoneFormField().choices),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Site', ( (_('Site'), (
'name', 'slug', 'status', 'region', 'group', 'facility', 'asns', 'time_zone', 'description', 'tags', 'name', 'slug', 'status', 'region', 'group', 'facility', 'asns', 'time_zone', 'description', 'tags',
)), )),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
('Contact Info', ('physical_address', 'shipping_address', 'latitude', 'longitude')), (_('Contact Info'), ('physical_address', 'shipping_address', 'latitude', 'longitude')),
) )
class Meta: class Meta:
@ -159,10 +164,12 @@ class SiteForm(TenancyForm, NetBoxModelForm):
class LocationForm(TenancyForm, NetBoxModelForm): class LocationForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
selector=True selector=True
) )
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -172,8 +179,8 @@ class LocationForm(TenancyForm, NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Location', ('site', 'parent', 'name', 'slug', 'status', 'description', 'tags')), (_('Location'), ('site', 'parent', 'name', 'slug', 'status', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -187,7 +194,7 @@ class RackRoleForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Rack Role', ( (_('Rack Role'), (
'name', 'slug', 'color', 'description', 'tags', 'name', 'slug', 'color', 'description', 'tags',
)), )),
) )
@ -201,10 +208,12 @@ class RackRoleForm(NetBoxModelForm):
class RackForm(TenancyForm, NetBoxModelForm): class RackForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
selector=True selector=True
) )
location = DynamicModelChoiceField( location = DynamicModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -212,6 +221,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
} }
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=RackRole.objects.all(), queryset=RackRole.objects.all(),
required=False required=False
) )
@ -228,14 +238,17 @@ class RackForm(TenancyForm, NetBoxModelForm):
class RackReservationForm(TenancyForm, NetBoxModelForm): class RackReservationForm(TenancyForm, NetBoxModelForm):
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
selector=True selector=True
) )
units = NumericArrayField( units = NumericArrayField(
label=_('Units'),
base_field=forms.IntegerField(), base_field=forms.IntegerField(),
help_text=_("Comma-separated list of numeric unit IDs. A range may be specified using a hyphen.") help_text=_("Comma-separated list of numeric unit IDs. A range may be specified using a hyphen.")
) )
user = forms.ModelChoiceField( user = forms.ModelChoiceField(
label=_('User'),
queryset=get_user_model().objects.order_by( queryset=get_user_model().objects.order_by(
'username' 'username'
) )
@ -243,8 +256,8 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Reservation', ('rack', 'units', 'user', 'description', 'tags')), (_('Reservation'), ('rack', 'units', 'user', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -258,7 +271,7 @@ class ManufacturerForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Manufacturer', ( (_('Manufacturer'), (
'name', 'slug', 'description', 'tags', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -272,23 +285,26 @@ class ManufacturerForm(NetBoxModelForm):
class DeviceTypeForm(NetBoxModelForm): class DeviceTypeForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField( manufacturer = DynamicModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all() queryset=Manufacturer.objects.all()
) )
default_platform = DynamicModelChoiceField( default_platform = DynamicModelChoiceField(
label=_('Default platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False required=False
) )
slug = SlugField( slug = SlugField(
label=_('Slug'),
slug_source='model' slug_source='model'
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Device Type', ('manufacturer', 'model', 'slug', 'default_platform', 'description', 'tags')), (_('Device Type'), ('manufacturer', 'model', 'slug', 'default_platform', 'description', 'tags')),
('Chassis', ( (_('Chassis'), (
'u_height', 'is_full_depth', 'part_number', 'subdevice_role', 'airflow', 'weight', 'weight_unit', '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: class Meta:
@ -310,13 +326,14 @@ class DeviceTypeForm(NetBoxModelForm):
class ModuleTypeForm(NetBoxModelForm): class ModuleTypeForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField( manufacturer = DynamicModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all() queryset=Manufacturer.objects.all()
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Module Type', ('manufacturer', 'model', 'part_number', 'description', 'tags')), (_('Module Type'), ('manufacturer', 'model', 'part_number', 'description', 'tags')),
('Weight', ('weight', 'weight_unit')) (_('Weight'), ('weight', 'weight_unit'))
) )
class Meta: class Meta:
@ -328,13 +345,14 @@ class ModuleTypeForm(NetBoxModelForm):
class DeviceRoleForm(NetBoxModelForm): class DeviceRoleForm(NetBoxModelForm):
config_template = DynamicModelChoiceField( config_template = DynamicModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Device Role', ( (_('Device Role'), (
'name', 'slug', 'color', 'vm_role', 'config_template', 'description', 'tags', 'name', 'slug', 'color', 'vm_role', 'config_template', 'description', 'tags',
)), )),
) )
@ -348,19 +366,22 @@ class DeviceRoleForm(NetBoxModelForm):
class PlatformForm(NetBoxModelForm): class PlatformForm(NetBoxModelForm):
manufacturer = DynamicModelChoiceField( manufacturer = DynamicModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
required=False required=False
) )
config_template = DynamicModelChoiceField( config_template = DynamicModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
required=False required=False
) )
slug = SlugField( slug = SlugField(
label=_('Slug'),
max_length=64 max_length=64
) )
fieldsets = ( fieldsets = (
('Platform', ('name', 'slug', 'manufacturer', 'config_template', 'description', 'tags')), (_('Platform'), ('name', 'slug', 'manufacturer', 'config_template', 'description', 'tags')),
) )
class Meta: class Meta:
@ -372,10 +393,12 @@ class PlatformForm(NetBoxModelForm):
class DeviceForm(TenancyForm, NetBoxModelForm): class DeviceForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
selector=True selector=True
) )
location = DynamicModelChoiceField( location = DynamicModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -386,6 +409,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
} }
) )
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -394,6 +418,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
} }
) )
position = forms.DecimalField( position = forms.DecimalField(
label=_('Position'),
required=False, required=False,
help_text=_("The lowest-numbered unit occupied by the device"), help_text=_("The lowest-numbered unit occupied by the device"),
widget=APISelect( widget=APISelect(
@ -405,17 +430,21 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
) )
) )
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
label=_('Device type'),
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
selector=True selector=True
) )
device_role = DynamicModelChoiceField( device_role = DynamicModelChoiceField(
label=_('Device role'),
queryset=DeviceRole.objects.all() queryset=DeviceRole.objects.all()
) )
platform = DynamicModelChoiceField( platform = DynamicModelChoiceField(
label=_('Platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False required=False
) )
cluster = DynamicModelChoiceField( cluster = DynamicModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
selector=True selector=True
@ -426,6 +455,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
label='' label=''
) )
virtual_chassis = DynamicModelChoiceField( virtual_chassis = DynamicModelChoiceField(
label=_('Virtual chassis'),
queryset=VirtualChassis.objects.all(), queryset=VirtualChassis.objects.all(),
required=False, required=False,
selector=True selector=True
@ -441,6 +471,7 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
help_text=_("The priority of the device in the virtual chassis") help_text=_("The priority of the device in the virtual chassis")
) )
config_template = DynamicModelChoiceField( config_template = DynamicModelChoiceField(
label=_('Config template'),
queryset=ConfigTemplate.objects.all(), queryset=ConfigTemplate.objects.all(),
required=False required=False
) )
@ -518,36 +549,41 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
class ModuleForm(ModuleCommonForm, NetBoxModelForm): class ModuleForm(ModuleCommonForm, NetBoxModelForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
initial_params={ initial_params={
'modulebays': '$module_bay' 'modulebays': '$module_bay'
} }
) )
module_bay = DynamicModelChoiceField( module_bay = DynamicModelChoiceField(
label=_('Module bay'),
queryset=ModuleBay.objects.all(), queryset=ModuleBay.objects.all(),
query_params={ query_params={
'device_id': '$device' 'device_id': '$device'
} }
) )
module_type = DynamicModelChoiceField( module_type = DynamicModelChoiceField(
label=_('Module type'),
queryset=ModuleType.objects.all(), queryset=ModuleType.objects.all(),
selector=True selector=True
) )
comments = CommentField() comments = CommentField()
replicate_components = forms.BooleanField( replicate_components = forms.BooleanField(
label=_('Replicate components'),
required=False, required=False,
initial=True, initial=True,
help_text=_("Automatically populate components associated with this module type") help_text=_("Automatically populate components associated with this module type")
) )
adopt_components = forms.BooleanField( adopt_components = forms.BooleanField(
label=_('Adopt components'),
required=False, required=False,
initial=False, initial=False,
help_text=_("Adopt already existing components") help_text=_("Adopt already existing components")
) )
fieldsets = ( fieldsets = (
('Module', ('device', 'module_bay', 'module_type', 'status', 'description', 'tags')), (_('Module'), ('device', 'module_bay', 'module_type', 'status', 'description', 'tags')),
('Hardware', ( (_('Hardware'), (
'serial', 'asset_tag', 'replicate_components', 'adopt_components', 'serial', 'asset_tag', 'replicate_components', 'adopt_components',
)), )),
) )
@ -581,17 +617,19 @@ class CableForm(TenancyForm, NetBoxModelForm):
] ]
error_messages = { error_messages = {
'length': { 'length': {
'max_value': 'Maximum length is 32767 (any unit)' 'max_value': _('Maximum length is 32767 (any unit)')
} }
} }
class PowerPanelForm(NetBoxModelForm): class PowerPanelForm(NetBoxModelForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
selector=True selector=True
) )
location = DynamicModelChoiceField( location = DynamicModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -613,10 +651,12 @@ class PowerPanelForm(NetBoxModelForm):
class PowerFeedForm(TenancyForm, NetBoxModelForm): class PowerFeedForm(TenancyForm, NetBoxModelForm):
power_panel = DynamicModelChoiceField( power_panel = DynamicModelChoiceField(
label=_('Power panel'),
queryset=PowerPanel.objects.all(), queryset=PowerPanel.objects.all(),
selector=True selector=True
) )
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
selector=True selector=True
@ -624,9 +664,9 @@ class PowerFeedForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Power Feed', ('power_panel', 'rack', 'name', 'status', 'type', 'description', 'mark_connected', 'tags')), (_('Power Feed'), ('power_panel', 'rack', 'name', 'status', 'type', 'description', 'mark_connected', 'tags')),
('Characteristics', ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')), (_('Characteristics'), ('supply', 'voltage', 'amperage', 'phase', 'max_utilization')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -643,6 +683,7 @@ class PowerFeedForm(TenancyForm, NetBoxModelForm):
class VirtualChassisForm(NetBoxModelForm): class VirtualChassisForm(NetBoxModelForm):
master = forms.ModelChoiceField( master = forms.ModelChoiceField(
label=_('Master'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
) )
@ -706,6 +747,7 @@ class DeviceVCMembershipForm(forms.ModelForm):
class VCMemberSelectForm(BootstrapMixin, forms.Form): class VCMemberSelectForm(BootstrapMixin, forms.Form):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
query_params={ query_params={
'virtual_chassis_id': 'null', 'virtual_chassis_id': 'null',
@ -728,6 +770,7 @@ class VCMemberSelectForm(BootstrapMixin, forms.Form):
class ComponentTemplateForm(BootstrapMixin, forms.ModelForm): class ComponentTemplateForm(BootstrapMixin, forms.ModelForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
label=_('Device type'),
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
@ -741,10 +784,12 @@ class ComponentTemplateForm(BootstrapMixin, forms.ModelForm):
class ModularComponentTemplateForm(ComponentTemplateForm): class ModularComponentTemplateForm(ComponentTemplateForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
label=_('Device type'),
queryset=DeviceType.objects.all().all(), queryset=DeviceType.objects.all().all(),
required=False required=False
) )
module_type = DynamicModelChoiceField( module_type = DynamicModelChoiceField(
label=_('Module type'),
queryset=ModuleType.objects.all(), queryset=ModuleType.objects.all(),
required=False required=False
) )
@ -797,6 +842,7 @@ class PowerPortTemplateForm(ModularComponentTemplateForm):
class PowerOutletTemplateForm(ModularComponentTemplateForm): class PowerOutletTemplateForm(ModularComponentTemplateForm):
power_port = DynamicModelChoiceField( power_port = DynamicModelChoiceField(
label=_('Power port'),
queryset=PowerPortTemplate.objects.all(), queryset=PowerPortTemplate.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -817,6 +863,7 @@ class PowerOutletTemplateForm(ModularComponentTemplateForm):
class InterfaceTemplateForm(ModularComponentTemplateForm): class InterfaceTemplateForm(ModularComponentTemplateForm):
bridge = DynamicModelChoiceField( bridge = DynamicModelChoiceField(
label=_('Bridge'),
queryset=InterfaceTemplate.objects.all(), queryset=InterfaceTemplate.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -827,8 +874,8 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
fieldsets = ( fieldsets = (
(None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge')), (None, ('device_type', 'module_type', 'name', 'label', 'type', 'enabled', 'mgmt_only', 'description', 'bridge')),
('PoE', ('poe_mode', 'poe_type')), (_('PoE'), ('poe_mode', 'poe_type')),
('Wireless', ('rf_role',)) (_('Wireless'), ('rf_role',)),
) )
class Meta: class Meta:
@ -840,6 +887,7 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
class FrontPortTemplateForm(ModularComponentTemplateForm): class FrontPortTemplateForm(ModularComponentTemplateForm):
rear_port = DynamicModelChoiceField( rear_port = DynamicModelChoiceField(
label=_('Rear port'),
queryset=RearPortTemplate.objects.all(), queryset=RearPortTemplate.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -901,6 +949,7 @@ class DeviceBayTemplateForm(ComponentTemplateForm):
class InventoryItemTemplateForm(ComponentTemplateForm): class InventoryItemTemplateForm(ComponentTemplateForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=InventoryItemTemplate.objects.all(), queryset=InventoryItemTemplate.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -908,10 +957,12 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
} }
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=InventoryItemRole.objects.all(), queryset=InventoryItemRole.objects.all(),
required=False required=False
) )
manufacturer = DynamicModelChoiceField( manufacturer = DynamicModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
required=False required=False
) )
@ -947,6 +998,7 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
class DeviceComponentForm(NetBoxModelForm): class DeviceComponentForm(NetBoxModelForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
selector=True selector=True
) )
@ -961,6 +1013,7 @@ class DeviceComponentForm(NetBoxModelForm):
class ModularDeviceComponentForm(DeviceComponentForm): class ModularDeviceComponentForm(DeviceComponentForm):
module = DynamicModelChoiceField( module = DynamicModelChoiceField(
label=_('Module'),
queryset=Module.objects.all(), queryset=Module.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -1017,6 +1070,7 @@ class PowerPortForm(ModularDeviceComponentForm):
class PowerOutletForm(ModularDeviceComponentForm): class PowerOutletForm(ModularDeviceComponentForm):
power_port = DynamicModelChoiceField( power_port = DynamicModelChoiceField(
label=_('Power port'),
queryset=PowerPort.objects.all(), queryset=PowerPort.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -1043,7 +1097,7 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
vdcs = DynamicModelMultipleChoiceField( vdcs = DynamicModelMultipleChoiceField(
queryset=VirtualDeviceContext.objects.all(), queryset=VirtualDeviceContext.objects.all(),
required=False, required=False,
label='Virtual Device Contexts', label=_('Virtual device contexts'),
query_params={ query_params={
'device_id': '$device', 'device_id': '$device',
} }
@ -1121,13 +1175,13 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
) )
fieldsets = ( fieldsets = (
('Interface', ('device', 'module', 'name', 'label', 'type', 'speed', 'duplex', 'description', 'tags')), (_('Interface'), ('device', 'module', 'name', 'label', 'type', 'speed', 'duplex', 'description', 'tags')),
('Addressing', ('vrf', 'mac_address', 'wwn')), (_('Addressing'), ('vrf', 'mac_address', 'wwn')),
('Operation', ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')), (_('Operation'), ('vdcs', 'mtu', 'tx_power', 'enabled', 'mgmt_only', 'mark_connected')),
('Related Interfaces', ('parent', 'bridge', 'lag')), (_('Related Interfaces'), ('parent', 'bridge', 'lag')),
('PoE', ('poe_mode', 'poe_type')), (_('PoE'), ('poe_mode', 'poe_type')),
('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')), (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
('Wireless', ( (_('Wireless'), (
'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'wireless_lan_group', 'wireless_lans', '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): class InventoryItemForm(DeviceComponentForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=InventoryItem.objects.all(), queryset=InventoryItem.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -1240,10 +1295,12 @@ class InventoryItemForm(DeviceComponentForm):
} }
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=InventoryItemRole.objects.all(), queryset=InventoryItemRole.objects.all(),
required=False required=False
) )
manufacturer = DynamicModelChoiceField( manufacturer = DynamicModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
required=False required=False
) )
@ -1307,8 +1364,8 @@ class InventoryItemForm(DeviceComponentForm):
) )
fieldsets = ( fieldsets = (
('Inventory Item', ('device', 'parent', 'name', 'label', 'role', 'description', 'tags')), (_('Inventory Item'), ('device', 'parent', 'name', 'label', 'role', 'description', 'tags')),
('Hardware', ('manufacturer', 'part_id', 'serial', 'asset_tag')), (_('Hardware'), ('manufacturer', 'part_id', 'serial', 'asset_tag')),
) )
class Meta: class Meta:
@ -1359,7 +1416,7 @@ class InventoryItemForm(DeviceComponentForm):
) if self.cleaned_data[field] ) if self.cleaned_data[field]
] ]
if len(selected_objects) > 1: 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: elif selected_objects:
self.instance.component = self.cleaned_data[selected_objects[0]] self.instance.component = self.cleaned_data[selected_objects[0]]
else: else:
@ -1373,7 +1430,7 @@ class InventoryItemRoleForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Inventory Item Role', ( (_('Inventory Item Role'), (
'name', 'slug', 'color', 'description', 'tags', 'name', 'slug', 'color', 'description', 'tags',
)), )),
) )
@ -1387,12 +1444,13 @@ class InventoryItemRoleForm(NetBoxModelForm):
class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm): class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
selector=True selector=True
) )
primary_ip4 = DynamicModelChoiceField( primary_ip4 = DynamicModelChoiceField(
queryset=IPAddress.objects.all(), queryset=IPAddress.objects.all(),
label='Primary IPv4', label=_('Primary IPv4'),
required=False, required=False,
query_params={ query_params={
'device_id': '$device', 'device_id': '$device',
@ -1401,7 +1459,7 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
) )
primary_ip6 = DynamicModelChoiceField( primary_ip6 = DynamicModelChoiceField(
queryset=IPAddress.objects.all(), queryset=IPAddress.objects.all(),
label='Primary IPv6', label=_('Primary IPv6'),
required=False, required=False,
query_params={ query_params={
'device_id': '$device', 'device_id': '$device',
@ -1410,8 +1468,8 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
) )
fieldsets = ( fieldsets = (
('Virtual Device Context', ('device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tags')), (_('Virtual Device Context'), ('device', 'name', 'status', 'identifier', 'primary_ip4', 'primary_ip6', 'tags')),
('Tenancy', ('tenant_group', 'tenant')) (_('Tenancy'), ('tenant_group', 'tenant'))
) )
class Meta: class Meta:

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy as _
from dcim.models import * from dcim.models import *
from netbox.forms import NetBoxModelForm 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 Subclass this form when facilitating the creation of one or more component or component template objects based on
a name pattern. a name pattern.
""" """
name = ExpandableNameField() name = ExpandableNameField(
label=_('Name'),
)
label = ExpandableNameField( label = ExpandableNameField(
label=_('Label'),
required=False, required=False,
help_text=_('Alphanumeric ranges are supported. (Must match the number of objects being created.)') 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]) value_count = len(self.cleaned_data[field_name])
if self.cleaned_data[field_name] and value_count != pattern_count: if self.cleaned_data[field_name] and value_count != pattern_count:
raise forms.ValidationError({ raise forms.ValidationError({
field_name: f'The provided pattern specifies {value_count} values, but {pattern_count} are ' field_name: _(
f'expected.' "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') }, code='label_pattern_mismatch')
@ -222,12 +226,14 @@ class InterfaceCreateForm(ComponentCreateForm, model_forms.InterfaceForm):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if 'module' in self.fields: if 'module' in self.fields:
self.fields['name'].help_text += ' The string <code>{module}</code> will be replaced with the position ' \ self.fields['name'].help_text += _(
'of the assigned module, if any' "The string <code>{module}</code> will be replaced with the position of the assigned module, if any."
)
class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm): class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
selector=True, selector=True,
widget=APISelect( widget=APISelect(
@ -329,6 +335,7 @@ class InventoryItemCreateForm(ComponentCreateForm, model_forms.InventoryItemForm
class VirtualChassisCreateForm(NetBoxModelForm): class VirtualChassisCreateForm(NetBoxModelForm):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -336,6 +343,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
} }
) )
site_group = DynamicModelChoiceField( site_group = DynamicModelChoiceField(
label=_('Site group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -343,6 +351,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
} }
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -351,6 +360,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
} }
) )
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
null_option='None', null_option='None',
@ -359,6 +369,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
} }
) )
members = DynamicModelMultipleChoiceField( members = DynamicModelMultipleChoiceField(
label=_('Members'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -367,6 +378,7 @@ class VirtualChassisCreateForm(NetBoxModelForm):
} }
) )
initial_position = forms.IntegerField( initial_position = forms.IntegerField(
label=_('Initial position'),
initial=1, initial=1,
required=False, required=False,
help_text=_('Position of the first member device. Increases by one for each additional member.') 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: if self.cleaned_data['members'] and self.cleaned_data['initial_position'] is None:
raise forms.ValidationError({ 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): def save(self, *args, **kwargs):

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import InterfacePoEModeChoices, InterfacePoETypeChoices, InterfaceTypeChoices, PortTypeChoices
from dcim.models import * from dcim.models import *
@ -57,6 +57,7 @@ class PowerPortTemplateImportForm(ComponentTemplateImportForm):
class PowerOutletTemplateImportForm(ComponentTemplateImportForm): class PowerOutletTemplateImportForm(ComponentTemplateImportForm):
power_port = forms.ModelChoiceField( power_port = forms.ModelChoiceField(
label=_('Power port'),
queryset=PowerPortTemplate.objects.all(), queryset=PowerPortTemplate.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False
@ -85,6 +86,7 @@ class PowerOutletTemplateImportForm(ComponentTemplateImportForm):
class InterfaceTemplateImportForm(ComponentTemplateImportForm): class InterfaceTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=InterfaceTypeChoices.CHOICES choices=InterfaceTypeChoices.CHOICES
) )
poe_mode = forms.ChoiceField( poe_mode = forms.ChoiceField(
@ -113,9 +115,11 @@ class InterfaceTemplateImportForm(ComponentTemplateImportForm):
class FrontPortTemplateImportForm(ComponentTemplateImportForm): class FrontPortTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=PortTypeChoices.CHOICES choices=PortTypeChoices.CHOICES
) )
rear_port = forms.ModelChoiceField( rear_port = forms.ModelChoiceField(
label=_('Rear port'),
queryset=RearPortTemplate.objects.all(), queryset=RearPortTemplate.objects.all(),
to_field_name='name' to_field_name='name'
) )
@ -143,6 +147,7 @@ class FrontPortTemplateImportForm(ComponentTemplateImportForm):
class RearPortTemplateImportForm(ComponentTemplateImportForm): class RearPortTemplateImportForm(ComponentTemplateImportForm):
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=PortTypeChoices.CHOICES choices=PortTypeChoices.CHOICES
) )
@ -173,15 +178,18 @@ class DeviceBayTemplateImportForm(ComponentTemplateImportForm):
class InventoryItemTemplateImportForm(ComponentTemplateImportForm): class InventoryItemTemplateImportForm(ComponentTemplateImportForm):
parent = forms.ModelChoiceField( parent = forms.ModelChoiceField(
label=_('Parent'),
queryset=InventoryItemTemplate.objects.all(), queryset=InventoryItemTemplate.objects.all(),
required=False required=False
) )
role = forms.ModelChoiceField( role = forms.ModelChoiceField(
label=_('Role'),
queryset=InventoryItemRole.objects.all(), queryset=InventoryItemRole.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False
) )
manufacturer = forms.ModelChoiceField( manufacturer = forms.ModelChoiceField(
label=_('Manufacturer'),
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='name', to_field_name='name',
required=False required=False

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import *
from extras.models import * from extras.models import *
@ -27,16 +27,20 @@ class CustomFieldBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
group_name = forms.CharField( group_name = forms.CharField(
label=_('Group name'),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
required=False required=False
) )
required = forms.NullBooleanField( required = forms.NullBooleanField(
label=_('Required'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
choice_set = DynamicModelChoiceField( choice_set = DynamicModelChoiceField(
@ -50,6 +54,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
initial='' initial=''
) )
is_cloneable = forms.NullBooleanField( is_cloneable = forms.NullBooleanField(
label=_('Is cloneable'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
@ -83,17 +88,21 @@ class CustomLinkBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
new_window = forms.NullBooleanField( new_window = forms.NullBooleanField(
label=_('New window'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
button_class = forms.ChoiceField( button_class = forms.ChoiceField(
label=_('Button class'),
choices=add_blank_choice(CustomLinkButtonClassChoices), choices=add_blank_choice(CustomLinkButtonClassChoices),
required=False required=False
) )
@ -105,18 +114,22 @@ class ExportTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
mime_type = forms.CharField( mime_type = forms.CharField(
label=_('MIME type'),
max_length=50, max_length=50,
required=False required=False
) )
file_extension = forms.CharField( file_extension = forms.CharField(
label=_('File extension'),
max_length=15, max_length=15,
required=False required=False
) )
as_attachment = forms.NullBooleanField( as_attachment = forms.NullBooleanField(
label=_('As attachment'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
@ -130,17 +143,21 @@ class SavedFilterBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
shared = forms.NullBooleanField( shared = forms.NullBooleanField(
label=_('Shared'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
@ -154,26 +171,32 @@ class WebhookBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
type_create = forms.NullBooleanField( type_create = forms.NullBooleanField(
label=_('On create'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
type_update = forms.NullBooleanField( type_update = forms.NullBooleanField(
label=_('On update'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
type_delete = forms.NullBooleanField( type_delete = forms.NullBooleanField(
label=_('On delete'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
type_job_start = forms.NullBooleanField( type_job_start = forms.NullBooleanField(
label=_('On job start'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
type_job_end = forms.NullBooleanField( type_job_end = forms.NullBooleanField(
label=_('On job end'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
@ -192,6 +215,7 @@ class WebhookBulkEditForm(BulkEditForm):
label=_('SSL verification') label=_('SSL verification')
) )
secret = forms.CharField( secret = forms.CharField(
label=_('Secret'),
required=False required=False
) )
ca_file_path = forms.CharField( ca_file_path = forms.CharField(
@ -208,9 +232,11 @@ class TagBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
color = ColorField( color = ColorField(
label=_('Color'),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -224,14 +250,17 @@ class ConfigContextBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False, required=False,
min_value=0 min_value=0
) )
is_active = forms.NullBooleanField( is_active = forms.NullBooleanField(
label=_('Is active'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
required=False, required=False,
max_length=100 max_length=100
) )
@ -245,6 +274,7 @@ class ConfigTemplateBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -258,10 +288,12 @@ class JournalEntryBulkEditForm(BulkEditForm):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
kind = forms.ChoiceField( kind = forms.ChoiceField(
label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices), choices=add_blank_choice(JournalEntryKindChoices),
required=False required=False
) )
comments = forms.CharField( comments = forms.CharField(
label=_('Comments'),
required=False, required=False,
widget=forms.Textarea() widget=forms.Textarea()
) )

View File

@ -2,7 +2,7 @@ from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms import SimpleArrayField from django.contrib.postgres.forms import SimpleArrayField
from django.utils.safestring import mark_safe 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.choices import *
from extras.models import * from extras.models import *
@ -28,27 +28,32 @@ __all__ = (
class CustomFieldImportForm(CSVModelForm): class CustomFieldImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'), limit_choices_to=FeatureQuery('custom_fields'),
help_text=_("One or more assigned object types") help_text=_("One or more assigned object types")
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=CustomFieldTypeChoices, choices=CustomFieldTypeChoices,
help_text=_('Field data type (e.g. text, integer, etc.)') help_text=_('Field data type (e.g. text, integer, etc.)')
) )
object_type = CSVContentTypeField( object_type = CSVContentTypeField(
label=_('Object type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'), limit_choices_to=FeatureQuery('custom_fields'),
required=False, required=False,
help_text=_("Object type (for object or multi-object fields)") help_text=_("Object type (for object or multi-object fields)")
) )
choice_set = CSVModelChoiceField( choice_set = CSVModelChoiceField(
label=_('Choice set'),
queryset=CustomFieldChoiceSet.objects.all(), queryset=CustomFieldChoiceSet.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Choice set (for selection fields)') help_text=_('Choice set (for selection fields)')
) )
ui_visibility = CSVChoiceField( ui_visibility = CSVChoiceField(
label=_('UI visibility'),
choices=CustomFieldVisibilityChoices, choices=CustomFieldVisibilityChoices,
help_text=_('How the custom field is displayed in the user interface') help_text=_('How the custom field is displayed in the user interface')
) )
@ -83,6 +88,7 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
class CustomLinkImportForm(CSVModelForm): class CustomLinkImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links'), limit_choices_to=FeatureQuery('custom_links'),
help_text=_("One or more assigned object types") help_text=_("One or more assigned object types")
@ -98,6 +104,7 @@ class CustomLinkImportForm(CSVModelForm):
class ExportTemplateImportForm(CSVModelForm): class ExportTemplateImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('export_templates'), limit_choices_to=FeatureQuery('export_templates'),
help_text=_("One or more assigned object types") help_text=_("One or more assigned object types")
@ -121,6 +128,7 @@ class ConfigTemplateImportForm(CSVModelForm):
class SavedFilterImportForm(CSVModelForm): class SavedFilterImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
help_text=_("One or more assigned object types") help_text=_("One or more assigned object types")
) )
@ -134,6 +142,7 @@ class SavedFilterImportForm(CSVModelForm):
class WebhookImportForm(CSVModelForm): class WebhookImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks'), limit_choices_to=FeatureQuery('webhooks'),
help_text=_("One or more assigned object types") help_text=_("One or more assigned object types")
@ -165,6 +174,7 @@ class JournalEntryImportForm(NetBoxModelImportForm):
label=_('Assigned object type'), label=_('Assigned object type'),
) )
kind = CSVChoiceField( kind = CSVChoiceField(
label=_('Kind'),
choices=JournalEntryKindChoices, choices=JournalEntryKindChoices,
help_text=_('The classification of entry') help_text=_('The classification of entry')
) )

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType 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 core.models import DataFile, DataSource
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
@ -39,7 +39,7 @@ __all__ = (
class CustomFieldFilterForm(SavedFiltersMixin, FilterForm): class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Attributes', ( (_('Attributes'), (
'type', 'content_type_id', 'group_name', 'weight', 'required', 'choice_set_id', 'ui_visibility', 'type', 'content_type_id', 'group_name', 'weight', 'required', 'choice_set_id', 'ui_visibility',
'is_cloneable', 'is_cloneable',
)), )),
@ -55,12 +55,15 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
label=_('Field type') label=_('Field type')
) )
group_name = forms.CharField( group_name = forms.CharField(
label=_('Group name'),
required=False required=False
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
required = forms.NullBooleanField( required = forms.NullBooleanField(
label=_('Required'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -77,6 +80,7 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
label=_('UI visibility') label=_('UI visibility')
) )
is_cloneable = forms.NullBooleanField( is_cloneable = forms.NullBooleanField(
label=_('Is cloneable'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -104,22 +108,26 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
(_('Attributes'), ('content_types', 'enabled', 'new_window', 'weight')), (_('Attributes'), ('content_types', 'enabled', 'new_window', 'weight')),
) )
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('custom_links').get_query()), queryset=ContentType.objects.filter(FeatureQuery('custom_links').get_query()),
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
new_window = forms.NullBooleanField( new_window = forms.NullBooleanField(
label=_('New window'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
@ -127,8 +135,8 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm): class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Data', ('data_source_id', 'data_file_id')), (_('Data'), ('data_source_id', 'data_file_id')),
('Attributes', ('content_types', 'mime_type', 'file_extension', 'as_attachment')), (_('Attributes'), ('content_types', 'mime_type', 'file_extension', 'as_attachment')),
) )
data_source_id = DynamicModelMultipleChoiceField( data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
@ -144,6 +152,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
} }
) )
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()), queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()),
required=False required=False
) )
@ -152,9 +161,11 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
label=_('MIME type') label=_('MIME type')
) )
file_extension = forms.CharField( file_extension = forms.CharField(
label=_('File extension'),
required=False required=False
) )
as_attachment = forms.NullBooleanField( as_attachment = forms.NullBooleanField(
label=_('As attachment'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -165,13 +176,15 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm): class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Attributes', ('content_type_id', 'name',)), (_('Attributes'), ('content_type_id', 'name',)),
) )
content_type_id = ContentTypeChoiceField( content_type_id = ContentTypeChoiceField(
label=_('Content type'),
queryset=ContentType.objects.filter(FeatureQuery('custom_fields').get_query()), queryset=ContentType.objects.filter(FeatureQuery('custom_fields').get_query()),
required=False required=False
) )
name = forms.CharField( name = forms.CharField(
label=_('Name'),
required=False required=False
) )
@ -179,25 +192,29 @@ class ImageAttachmentFilterForm(SavedFiltersMixin, FilterForm):
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm): class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Attributes', ('content_types', 'enabled', 'shared', 'weight')), (_('Attributes'), ('content_types', 'enabled', 'shared', 'weight')),
) )
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()), queryset=ContentType.objects.filter(FeatureQuery('export_templates').get_query()),
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
shared = forms.NullBooleanField( shared = forms.NullBooleanField(
label=_('Shared'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
) )
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
@ -205,8 +222,8 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
class WebhookFilterForm(SavedFiltersMixin, FilterForm): class WebhookFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Attributes', ('content_type_id', 'http_method', 'enabled')), (_('Attributes'), ('content_type_id', 'http_method', 'enabled')),
('Events', ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
) )
content_type_id = ContentTypeMultipleChoiceField( content_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.filter(FeatureQuery('webhooks').get_query()), queryset=ContentType.objects.filter(FeatureQuery('webhooks').get_query()),
@ -219,6 +236,7 @@ class WebhookFilterForm(SavedFiltersMixin, FilterForm):
label=_('HTTP method') label=_('HTTP method')
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -278,11 +296,11 @@ class TagFilterForm(SavedFiltersMixin, FilterForm):
class ConfigContextFilterForm(SavedFiltersMixin, FilterForm): class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag_id')), (None, ('q', 'filter_id', 'tag_id')),
('Data', ('data_source_id', 'data_file_id')), (_('Data'), ('data_source_id', 'data_file_id')),
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id', 'location_id')),
('Device', ('device_type_id', 'platform_id', 'role_id')), (_('Device'), ('device_type_id', 'platform_id', 'role_id')),
('Cluster', ('cluster_type_id', 'cluster_group_id', 'cluster_id')), (_('Cluster'), ('cluster_type_id', 'cluster_group_id', 'cluster_id')),
('Tenant', ('tenant_group_id', 'tenant_id')) (_('Tenant'), ('tenant_group_id', 'tenant_id'))
) )
data_source_id = DynamicModelMultipleChoiceField( data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
@ -368,7 +386,7 @@ class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm): class ConfigTemplateFilterForm(SavedFiltersMixin, FilterForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Data', ('data_source_id', 'data_file_id')), (_('Data'), ('data_source_id', 'data_file_id')),
) )
data_source_id = DynamicModelMultipleChoiceField( data_source_id = DynamicModelMultipleChoiceField(
queryset=DataSource.objects.all(), queryset=DataSource.objects.all(),
@ -400,8 +418,8 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
model = JournalEntry model = JournalEntry
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Creation', ('created_before', 'created_after', 'created_by_id')), (_('Creation'), ('created_before', 'created_after', 'created_by_id')),
('Attributes', ('assigned_object_type_id', 'kind')) (_('Attributes'), ('assigned_object_type_id', 'kind'))
) )
created_after = forms.DateTimeField( created_after = forms.DateTimeField(
required=False, required=False,
@ -430,6 +448,7 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
) )
) )
kind = forms.ChoiceField( kind = forms.ChoiceField(
label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices), choices=add_blank_choice(JournalEntryKindChoices),
required=False required=False
) )
@ -440,8 +459,8 @@ class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
model = ObjectChange model = ObjectChange
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (None, ('q', 'filter_id')),
('Time', ('time_before', 'time_after')), (_('Time'), ('time_before', 'time_after')),
('Attributes', ('action', 'user_id', 'changed_object_type_id')), (_('Attributes'), ('action', 'user_id', 'changed_object_type_id')),
) )
time_after = forms.DateTimeField( time_after = forms.DateTimeField(
required=False, required=False,
@ -454,6 +473,7 @@ class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
widget=DateTimePicker() widget=DateTimePicker()
) )
action = forms.ChoiceField( action = forms.ChoiceField(
label=_('Action'),
choices=add_blank_choice(ObjectChangeActionChoices), choices=add_blank_choice(ObjectChangeActionChoices),
required=False required=False
) )

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
__all__ = ( __all__ = (
'RenderMarkdownForm', 'RenderMarkdownForm',
@ -10,5 +11,6 @@ class RenderMarkdownForm(forms.Form):
Provides basic validation for markup to be rendered. Provides basic validation for markup to be rendered.
""" """
text = forms.CharField( text = forms.CharField(
label=_('Text'),
required=False required=False
) )

View File

@ -4,7 +4,7 @@ from django import forms
from django.conf import settings from django.conf import settings
from django.db.models import Q from django.db.models import Q
from django.contrib.contenttypes.models import ContentType 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 core.forms.mixins import SyncedDataMixin
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
@ -42,10 +42,12 @@ __all__ = (
class CustomFieldForm(BootstrapMixin, forms.ModelForm): class CustomFieldForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_fields'), limit_choices_to=FeatureQuery('custom_fields'),
) )
object_type = ContentTypeChoiceField( object_type = ContentTypeChoiceField(
label=_('Object type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
# TODO: Come up with a canonical way to register suitable models # 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']), 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 = ( fieldsets = (
('Custom Field', ( (_('Custom Field'), (
'content_types', 'name', 'label', 'group_name', 'type', 'object_type', 'required', 'description', 'content_types', 'name', 'label', 'group_name', 'type', 'object_type', 'required', 'description',
)), )),
('Behavior', ('search_weight', 'filter_logic', 'ui_visibility', 'weight', 'is_cloneable')), (_('Behavior'), ('search_weight', 'filter_logic', 'ui_visibility', 'weight', 'is_cloneable')),
('Values', ('default', 'choice_set')), (_('Values'), ('default', 'choice_set')),
('Validation', ('validation_minimum', 'validation_maximum', 'validation_regex')), (_('Validation'), ('validation_minimum', 'validation_maximum', 'validation_regex')),
) )
class Meta: class Meta:
@ -106,13 +108,14 @@ class CustomFieldChoiceSetForm(BootstrapMixin, forms.ModelForm):
class CustomLinkForm(BootstrapMixin, forms.ModelForm): class CustomLinkForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('custom_links') limit_choices_to=FeatureQuery('custom_links')
) )
fieldsets = ( fieldsets = (
('Custom Link', ('name', 'content_types', 'weight', 'group_name', 'button_class', 'enabled', 'new_window')), (_('Custom Link'), ('name', 'content_types', 'weight', 'group_name', 'button_class', 'enabled', 'new_window')),
('Templates', ('link_text', 'link_url')), (_('Templates'), ('link_text', 'link_url')),
) )
class Meta: class Meta:
@ -133,18 +136,20 @@ class CustomLinkForm(BootstrapMixin, forms.ModelForm):
class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm): class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('export_templates') limit_choices_to=FeatureQuery('export_templates')
) )
template_code = forms.CharField( template_code = forms.CharField(
label=_('Template code'),
required=False, required=False,
widget=forms.Textarea(attrs={'class': 'font-monospace'}) widget=forms.Textarea(attrs={'class': 'font-monospace'})
) )
fieldsets = ( fieldsets = (
('Export Template', ('name', 'content_types', 'description', 'template_code')), (_('Export Template'), ('name', 'content_types', 'description', 'template_code')),
('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')), (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
('Rendering', ('mime_type', 'file_extension', 'as_attachment')), (_('Rendering'), ('mime_type', 'file_extension', 'as_attachment')),
) )
class Meta: class Meta:
@ -165,7 +170,7 @@ class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean() super().clean()
if not self.cleaned_data.get('template_code') and not self.cleaned_data.get('data_file'): 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 return self.cleaned_data
@ -173,13 +178,14 @@ class ExportTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
class SavedFilterForm(BootstrapMixin, forms.ModelForm): class SavedFilterForm(BootstrapMixin, forms.ModelForm):
slug = SlugField() slug = SlugField()
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.all() queryset=ContentType.objects.all()
) )
parameters = JSONField() parameters = JSONField()
fieldsets = ( fieldsets = (
('Saved Filter', ('name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared')), (_('Saved Filter'), ('name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared')),
('Parameters', ('parameters',)), (_('Parameters'), ('parameters',)),
) )
class Meta: class Meta:
@ -198,6 +204,7 @@ class SavedFilterForm(BootstrapMixin, forms.ModelForm):
class BookmarkForm(BootstrapMixin, forms.ModelForm): class BookmarkForm(BootstrapMixin, forms.ModelForm):
object_type = ContentTypeChoiceField( object_type = ContentTypeChoiceField(
label=_('Object type'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('bookmarks').get_query() limit_choices_to=FeatureQuery('bookmarks').get_query()
) )
@ -209,29 +216,30 @@ class BookmarkForm(BootstrapMixin, forms.ModelForm):
class WebhookForm(BootstrapMixin, forms.ModelForm): class WebhookForm(BootstrapMixin, forms.ModelForm):
content_types = ContentTypeMultipleChoiceField( content_types = ContentTypeMultipleChoiceField(
label=_('Content types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('webhooks') limit_choices_to=FeatureQuery('webhooks')
) )
fieldsets = ( fieldsets = (
('Webhook', ('name', 'content_types', 'enabled')), (_('Webhook'), ('name', 'content_types', 'enabled')),
('Events', ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')), (_('Events'), ('type_create', 'type_update', 'type_delete', 'type_job_start', 'type_job_end')),
('HTTP Request', ( (_('HTTP Request'), (
'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret', 'payload_url', 'http_method', 'http_content_type', 'additional_headers', 'body_template', 'secret',
)), )),
('Conditions', ('conditions',)), (_('Conditions'), ('conditions',)),
('SSL', ('ssl_verification', 'ca_file_path')), (_('SSL'), ('ssl_verification', 'ca_file_path')),
) )
class Meta: class Meta:
model = Webhook model = Webhook
fields = '__all__' fields = '__all__'
labels = { labels = {
'type_create': 'Creations', 'type_create': _('Creations'),
'type_update': 'Updates', 'type_update': _('Updates'),
'type_delete': 'Deletions', 'type_delete': _('Deletions'),
'type_job_start': 'Job executions', 'type_job_start': _('Job executions'),
'type_job_end': 'Job terminations', 'type_job_end': _('Job terminations'),
} }
widgets = { widgets = {
'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}), 'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}),
@ -243,6 +251,7 @@ class WebhookForm(BootstrapMixin, forms.ModelForm):
class TagForm(BootstrapMixin, forms.ModelForm): class TagForm(BootstrapMixin, forms.ModelForm):
slug = SlugField() slug = SlugField()
object_types = ContentTypeMultipleChoiceField( object_types = ContentTypeMultipleChoiceField(
label=_('Object types'),
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=FeatureQuery('tags'), limit_choices_to=FeatureQuery('tags'),
required=False required=False
@ -261,65 +270,79 @@ class TagForm(BootstrapMixin, forms.ModelForm):
class ConfigContextForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm): class ConfigContextForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
regions = DynamicModelMultipleChoiceField( regions = DynamicModelMultipleChoiceField(
label=_('Regions'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False required=False
) )
site_groups = DynamicModelMultipleChoiceField( site_groups = DynamicModelMultipleChoiceField(
label=_('Site groups'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False required=False
) )
sites = DynamicModelMultipleChoiceField( sites = DynamicModelMultipleChoiceField(
label=_('Sites'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False required=False
) )
locations = DynamicModelMultipleChoiceField( locations = DynamicModelMultipleChoiceField(
label=_('Locations'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False required=False
) )
device_types = DynamicModelMultipleChoiceField( device_types = DynamicModelMultipleChoiceField(
label=_('Device types'),
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
required=False required=False
) )
roles = DynamicModelMultipleChoiceField( roles = DynamicModelMultipleChoiceField(
label=_('Roles'),
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
required=False required=False
) )
platforms = DynamicModelMultipleChoiceField( platforms = DynamicModelMultipleChoiceField(
label=_('Platforms'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False required=False
) )
cluster_types = DynamicModelMultipleChoiceField( cluster_types = DynamicModelMultipleChoiceField(
label=_('Cluster types'),
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
required=False required=False
) )
cluster_groups = DynamicModelMultipleChoiceField( cluster_groups = DynamicModelMultipleChoiceField(
label=_('Cluster groups'),
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
required=False required=False
) )
clusters = DynamicModelMultipleChoiceField( clusters = DynamicModelMultipleChoiceField(
label=_('Clusters'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False required=False
) )
tenant_groups = DynamicModelMultipleChoiceField( tenant_groups = DynamicModelMultipleChoiceField(
label=_('Tenat groups'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False required=False
) )
tenants = DynamicModelMultipleChoiceField( tenants = DynamicModelMultipleChoiceField(
label=_('Tenants'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
tags = DynamicModelMultipleChoiceField( tags = DynamicModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False
) )
data = JSONField( data = JSONField(
label=_('Data'),
required=False required=False
) )
fieldsets = ( fieldsets = (
('Config Context', ('name', 'weight', 'description', 'data', 'is_active')), (_('Config Context'), ('name', 'weight', 'description', 'data', 'is_active')),
('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')), (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
('Assignment', ( (_('Assignment'), (
'regions', 'site_groups', 'sites', 'locations', 'device_types', 'roles', 'platforms', 'cluster_types', 'regions', 'site_groups', 'sites', 'locations', 'device_types', 'roles', 'platforms', 'cluster_types',
'cluster_groups', 'clusters', 'tenant_groups', 'tenants', 'tags', 'cluster_groups', 'clusters', 'tenant_groups', 'tenants', 'tags',
)), )),
@ -351,25 +374,27 @@ class ConfigContextForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean() super().clean()
if not self.cleaned_data.get('data') and not self.cleaned_data.get('data_file'): 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 return self.cleaned_data
class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm): class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
tags = DynamicModelMultipleChoiceField( tags = DynamicModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False
) )
template_code = forms.CharField( template_code = forms.CharField(
label=_('Template code'),
required=False, required=False,
widget=forms.Textarea(attrs={'class': 'font-monospace'}) widget=forms.Textarea(attrs={'class': 'font-monospace'})
) )
fieldsets = ( fieldsets = (
('Config Template', ('name', 'description', 'environment_params', 'tags')), (_('Config Template'), ('name', 'description', 'environment_params', 'tags')),
('Content', ('template_code',)), (_('Content'), ('template_code',)),
('Data Source', ('data_source', 'data_file', 'auto_sync_enabled')), (_('Data Source'), ('data_source', 'data_file', 'auto_sync_enabled')),
) )
class Meta: class Meta:
@ -393,7 +418,7 @@ class ConfigTemplateForm(BootstrapMixin, SyncedDataMixin, forms.ModelForm):
super().clean() super().clean()
if not self.cleaned_data.get('template_code') and not self.cleaned_data.get('data_file'): 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 return self.cleaned_data
@ -409,6 +434,7 @@ class ImageAttachmentForm(BootstrapMixin, forms.ModelForm):
class JournalEntryForm(NetBoxModelForm): class JournalEntryForm(NetBoxModelForm):
kind = forms.ChoiceField( kind = forms.ChoiceField(
label=_('Kind'),
choices=add_blank_choice(JournalEntryKindChoices), choices=add_blank_choice(JournalEntryKindChoices),
required=False required=False
) )
@ -451,16 +477,16 @@ class ConfigRevisionForm(BootstrapMixin, forms.ModelForm, metaclass=ConfigFormMe
""" """
fieldsets = ( fieldsets = (
('Rack Elevations', ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH')), (_('Rack Elevations'), ('RACK_ELEVATION_DEFAULT_UNIT_HEIGHT', 'RACK_ELEVATION_DEFAULT_UNIT_WIDTH')),
('Power', ('POWERFEED_DEFAULT_VOLTAGE', 'POWERFEED_DEFAULT_AMPERAGE', 'POWERFEED_DEFAULT_MAX_UTILIZATION')), (_('Power'), ('POWERFEED_DEFAULT_VOLTAGE', 'POWERFEED_DEFAULT_AMPERAGE', 'POWERFEED_DEFAULT_MAX_UTILIZATION')),
('IPAM', ('ENFORCE_GLOBAL_UNIQUE', 'PREFER_IPV4')), (_('IPAM'), ('ENFORCE_GLOBAL_UNIQUE', 'PREFER_IPV4')),
('Security', ('ALLOWED_URL_SCHEMES',)), (_('Security'), ('ALLOWED_URL_SCHEMES',)),
('Banners', ('BANNER_LOGIN', 'BANNER_MAINTENANCE', 'BANNER_TOP', 'BANNER_BOTTOM')), (_('Banners'), ('BANNER_LOGIN', 'BANNER_MAINTENANCE', 'BANNER_TOP', 'BANNER_BOTTOM')),
('Pagination', ('PAGINATE_COUNT', 'MAX_PAGE_SIZE')), (_('Pagination'), ('PAGINATE_COUNT', 'MAX_PAGE_SIZE')),
('Validation', ('CUSTOM_VALIDATORS',)), (_('Validation'), ('CUSTOM_VALIDATORS',)),
('User Preferences', ('DEFAULT_USER_PREFERENCES',)), (_('User Preferences'), ('DEFAULT_USER_PREFERENCES',)),
('Miscellaneous', ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOB_RETENTION', 'MAPS_URL')), (_('Miscellaneous'), ('MAINTENANCE_MODE', 'GRAPHQL_ENABLED', 'CHANGELOG_RETENTION', 'JOB_RETENTION', 'MAPS_URL')),
('Config Revision', ('comment',)) (_('Config Revision'), ('comment',))
) )
class Meta: class Meta:
@ -487,11 +513,11 @@ class ConfigRevisionForm(BootstrapMixin, forms.ModelForm, metaclass=ConfigFormMe
help_text = self.fields[param.name].help_text help_text = self.fields[param.name].help_text
if help_text: if help_text:
help_text += '<br />' # Line break help_text += '<br />' # Line break
help_text += f'Current value: <strong>{value}</strong>' help_text += _('Current value: <strong>{value}</strong>').format(value=value)
if is_static: if is_static:
help_text += ' (defined statically)' help_text += _(' (defined statically)')
elif value == param.default: elif value == param.default:
help_text += ' (default)' help_text += _(' (default)')
self.fields[param.name].help_text = help_text self.fields[param.name].help_text = help_text
self.fields[param.name].initial = value self.fields[param.name].initial = value
if is_static: if is_static:

View File

@ -1,5 +1,5 @@
from django import forms 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 extras.choices import DurationChoices
from utilities.forms import BootstrapMixin from utilities.forms import BootstrapMixin
@ -33,7 +33,7 @@ class ReportForm(BootstrapMixin, forms.Form):
# Annotate the current system time for reference # Annotate the current system time for reference
now = local_now().strftime('%Y-%m-%d %H:%M:%S') now = local_now().strftime('%Y-%m-%d %H:%M:%S')
self.fields['schedule_at'].help_text += f' (current time: <strong>{now}</strong>)' self.fields['schedule_at'].help_text += _(' (current time: <strong>{now}</strong>)').format(now=now)
# Remove scheduling fields if scheduling is disabled # Remove scheduling fields if scheduling is disabled
if not scheduling_enabled: if not scheduling_enabled:

View File

@ -1,5 +1,5 @@
from django import forms 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 extras.choices import DurationChoices
from utilities.forms import BootstrapMixin from utilities.forms import BootstrapMixin
@ -39,7 +39,7 @@ class ScriptForm(BootstrapMixin, forms.Form):
# Annotate the current system time for reference # Annotate the current system time for reference
now = local_now().strftime('%Y-%m-%d %H:%M:%S') now = local_now().strftime('%Y-%m-%d %H:%M:%S')
self.fields['_schedule_at'].help_text += f' (current time: <strong>{now}</strong>)' self.fields['_schedule_at'].help_text += _(' (current time: <strong>{now}</strong>)').format(now=now)
# Remove scheduling fields if scheduling is disabled # Remove scheduling fields if scheduling is disabled
if not scheduling_enabled: if not scheduling_enabled:

View File

@ -1,5 +1,5 @@
from django import forms 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 import BootstrapMixin
from utilities.forms.fields import ExpandableIPAddressField from utilities.forms.fields import ExpandableIPAddressField

View File

@ -1,5 +1,5 @@
from django import forms 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 dcim.models import Region, Site, SiteGroup
from ipam.choices import * from ipam.choices import *
@ -37,6 +37,7 @@ __all__ = (
class VRFBulkEditForm(NetBoxModelBulkEditForm): class VRFBulkEditForm(NetBoxModelBulkEditForm):
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
@ -46,12 +47,11 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
label=_('Enforce unique space') label=_('Enforce unique space')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = VRF model = VRF
fieldsets = ( fieldsets = (
@ -62,16 +62,16 @@ class VRFBulkEditForm(NetBoxModelBulkEditForm):
class RouteTargetBulkEditForm(NetBoxModelBulkEditForm): class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = RouteTarget model = RouteTarget
fieldsets = ( fieldsets = (
@ -82,10 +82,12 @@ class RouteTargetBulkEditForm(NetBoxModelBulkEditForm):
class RIRBulkEditForm(NetBoxModelBulkEditForm): class RIRBulkEditForm(NetBoxModelBulkEditForm):
is_private = forms.NullBooleanField( is_private = forms.NullBooleanField(
label=_('Is private'),
required=False, required=False,
widget=BulkEditNullBooleanSelect widget=BulkEditNullBooleanSelect
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -104,10 +106,12 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR') label=_('RIR')
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -121,6 +125,7 @@ class ASNRangeBulkEditForm(NetBoxModelBulkEditForm):
class ASNBulkEditForm(NetBoxModelBulkEditForm): class ASNBulkEditForm(NetBoxModelBulkEditForm):
sites = DynamicModelMultipleChoiceField( sites = DynamicModelMultipleChoiceField(
label=_('Sites'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False required=False
) )
@ -130,16 +135,16 @@ class ASNBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR') label=_('RIR')
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = ASN model = ASN
fieldsets = ( fieldsets = (
@ -155,19 +160,20 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
label=_('RIR') label=_('RIR')
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
date_added = forms.DateField( date_added = forms.DateField(
label=_('Date added'),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = Aggregate model = Aggregate
fieldsets = ( fieldsets = (
@ -178,9 +184,11 @@ class AggregateBulkEditForm(NetBoxModelBulkEditForm):
class RoleBulkEditForm(NetBoxModelBulkEditForm): class RoleBulkEditForm(NetBoxModelBulkEditForm):
weight = forms.IntegerField( weight = forms.IntegerField(
label=_('Weight'),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -194,14 +202,17 @@ class RoleBulkEditForm(NetBoxModelBulkEditForm):
class PrefixBulkEditForm(NetBoxModelBulkEditForm): class PrefixBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False required=False
) )
site_group = DynamicModelChoiceField( site_group = DynamicModelChoiceField(
label=_('Site group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False required=False
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -215,19 +226,23 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF') label=_('VRF')
) )
prefix_length = forms.IntegerField( prefix_length = forms.IntegerField(
label=_('Prefix length'),
min_value=PREFIX_LENGTH_MIN, min_value=PREFIX_LENGTH_MIN,
max_value=PREFIX_LENGTH_MAX, max_value=PREFIX_LENGTH_MAX,
required=False required=False
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(PrefixStatusChoices), choices=add_blank_choice(PrefixStatusChoices),
required=False required=False
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
@ -242,18 +257,17 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
label=_('Treat as 100% utilized') label=_('Treat as 100% utilized')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = Prefix model = Prefix
fieldsets = ( fieldsets = (
(None, ('tenant', 'status', 'role', 'description')), (None, ('tenant', 'status', 'role', 'description')),
('Site', ('region', 'site_group', 'site')), (_('Site'), ('region', 'site_group', 'site')),
('Addressing', ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')), (_('Addressing'), ('vrf', 'prefix_length', 'is_pool', 'mark_utilized')),
) )
nullable_fields = ( nullable_fields = (
'site', 'vrf', 'tenant', 'role', 'description', 'comments', 'site', 'vrf', 'tenant', 'role', 'description', 'comments',
@ -267,14 +281,17 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF') label=_('VRF')
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(IPRangeStatusChoices), choices=add_blank_choice(IPRangeStatusChoices),
required=False required=False
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
@ -284,12 +301,11 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
label=_('Treat as 100% utilized') label=_('Treat as 100% utilized')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = IPRange model = IPRange
fieldsets = ( fieldsets = (
@ -307,19 +323,23 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label=_('VRF') label=_('VRF')
) )
mask_length = forms.IntegerField( mask_length = forms.IntegerField(
label=_('Mask length'),
min_value=IPADDRESS_MASK_LENGTH_MIN, min_value=IPADDRESS_MASK_LENGTH_MIN,
max_value=IPADDRESS_MASK_LENGTH_MAX, max_value=IPADDRESS_MASK_LENGTH_MAX,
required=False required=False
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(IPAddressStatusChoices), choices=add_blank_choice(IPAddressStatusChoices),
required=False required=False
) )
role = forms.ChoiceField( role = forms.ChoiceField(
label=_('Role'),
choices=add_blank_choice(IPAddressRoleChoices), choices=add_blank_choice(IPAddressRoleChoices),
required=False required=False
) )
@ -329,17 +349,16 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
label=_('DNS name') label=_('DNS name')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = IPAddress model = IPAddress
fieldsets = ( fieldsets = (
(None, ('status', 'role', 'tenant', 'description')), (None, ('status', 'role', 'tenant', 'description')),
('Addressing', ('vrf', 'mask_length', 'dns_name')), (_('Addressing'), ('vrf', 'mask_length', 'dns_name')),
) )
nullable_fields = ( nullable_fields = (
'vrf', 'role', 'tenant', 'dns_name', 'description', 'comments', 'vrf', 'role', 'tenant', 'dns_name', 'description', 'comments',
@ -348,6 +367,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm): class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
protocol = forms.ChoiceField( protocol = forms.ChoiceField(
label=_('Protocol'),
choices=add_blank_choice(FHRPGroupProtocolChoices), choices=add_blank_choice(FHRPGroupProtocolChoices),
required=False required=False
) )
@ -367,27 +387,28 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
label=_('Authentication key') label=_('Authentication key')
) )
name = forms.CharField( name = forms.CharField(
label=_('Name'),
max_length=100, max_length=100,
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = FHRPGroup model = FHRPGroup
fieldsets = ( fieldsets = (
(None, ('protocol', 'group_id', 'name', 'description')), (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') nullable_fields = ('auth_type', 'auth_key', 'name', 'description', 'comments')
class VLANGroupBulkEditForm(NetBoxModelBulkEditForm): class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False required=False
) )
@ -404,6 +425,7 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
label=_('Maximum child VLAN VID') label=_('Maximum child VLAN VID')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -417,14 +439,17 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
class VLANBulkEditForm(NetBoxModelBulkEditForm): class VLANBulkEditForm(NetBoxModelBulkEditForm):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False required=False
) )
site_group = DynamicModelChoiceField( site_group = DynamicModelChoiceField(
label=_('Site group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False required=False
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -433,6 +458,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=VLANGroup.objects.all(), queryset=VLANGroup.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -440,29 +466,31 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(VLANStatusChoices), choices=add_blank_choice(VLANStatusChoices),
required=False required=False
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = VLAN model = VLAN
fieldsets = ( fieldsets = (
(None, ('status', 'role', 'tenant', 'description')), (None, ('status', 'role', 'tenant', 'description')),
('Site & Group', ('region', 'site_group', 'site', 'group')), (_('Site & Group'), ('region', 'site_group', 'site', 'group')),
) )
nullable_fields = ( nullable_fields = (
'site', 'group', 'tenant', 'role', 'description', 'comments', 'site', 'group', 'tenant', 'role', 'description', 'comments',
@ -471,10 +499,12 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm): class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
protocol = forms.ChoiceField( protocol = forms.ChoiceField(
label=_('Protocol'),
choices=add_blank_choice(ServiceProtocolChoices), choices=add_blank_choice(ServiceProtocolChoices),
required=False required=False
) )
ports = NumericArrayField( ports = NumericArrayField(
label=_('Ports'),
base_field=forms.IntegerField( base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN, min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX max_value=SERVICE_PORT_MAX
@ -482,12 +512,11 @@ class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = ServiceTemplate model = ServiceTemplate
fieldsets = ( fieldsets = (
@ -502,20 +531,21 @@ class ServiceBulkEditForm(ServiceTemplateBulkEditForm):
class L2VPNBulkEditForm(NetBoxModelBulkEditForm): class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=add_blank_choice(L2VPNTypeChoices), choices=add_blank_choice(L2VPNTypeChoices),
required=False required=False
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = L2VPN model = L2VPN
fieldsets = ( fieldsets = (

View File

@ -2,7 +2,7 @@ from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db.models import Q 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 dcim.models import Device, Interface, Site
from ipam.choices import * from ipam.choices import *
@ -36,6 +36,7 @@ __all__ = (
class VRFImportForm(NetBoxModelImportForm): class VRFImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -49,6 +50,7 @@ class VRFImportForm(NetBoxModelImportForm):
class RouteTargetImportForm(NetBoxModelImportForm): class RouteTargetImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -70,11 +72,13 @@ class RIRImportForm(NetBoxModelImportForm):
class AggregateImportForm(NetBoxModelImportForm): class AggregateImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField( rir = CSVModelChoiceField(
label=_('RIR'),
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned RIR') help_text=_('Assigned RIR')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -88,11 +92,13 @@ class AggregateImportForm(NetBoxModelImportForm):
class ASNRangeImportForm(NetBoxModelImportForm): class ASNRangeImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField( rir = CSVModelChoiceField(
label=_('RIR'),
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned RIR') help_text=_('Assigned RIR')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -106,11 +112,13 @@ class ASNRangeImportForm(NetBoxModelImportForm):
class ASNImportForm(NetBoxModelImportForm): class ASNImportForm(NetBoxModelImportForm):
rir = CSVModelChoiceField( rir = CSVModelChoiceField(
label=_('RIR'),
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Assigned RIR') help_text=_('Assigned RIR')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -132,40 +140,47 @@ class RoleImportForm(NetBoxModelImportForm):
class PrefixImportForm(NetBoxModelImportForm): class PrefixImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned VRF') help_text=_('Assigned VRF')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned site') help_text=_('Assigned site')
) )
vlan_group = CSVModelChoiceField( vlan_group = CSVModelChoiceField(
label=_('VLAN group'),
queryset=VLANGroup.objects.all(), queryset=VLANGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_("VLAN's group (if any)") help_text=_("VLAN's group (if any)")
) )
vlan = CSVModelChoiceField( vlan = CSVModelChoiceField(
label=_('VLAN'),
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
required=False, required=False,
to_field_name='vid', to_field_name='vid',
help_text=_("Assigned VLAN") help_text=_("Assigned VLAN")
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=PrefixStatusChoices, choices=PrefixStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -211,22 +226,26 @@ class PrefixImportForm(NetBoxModelImportForm):
class IPRangeImportForm(NetBoxModelImportForm): class IPRangeImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned VRF') help_text=_('Assigned VRF')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=IPRangeStatusChoices, choices=IPRangeStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -243,45 +262,53 @@ class IPRangeImportForm(NetBoxModelImportForm):
class IPAddressImportForm(NetBoxModelImportForm): class IPAddressImportForm(NetBoxModelImportForm):
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned VRF') help_text=_('Assigned VRF')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=IPAddressStatusChoices, choices=IPAddressStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
role = CSVChoiceField( role = CSVChoiceField(
label=_('Role'),
choices=IPAddressRoleChoices, choices=IPAddressRoleChoices,
required=False, required=False,
help_text=_('Functional role') help_text=_('Functional role')
) )
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent device of assigned interface (if any)') help_text=_('Parent device of assigned interface (if any)')
) )
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent VM of assigned interface (if any)') help_text=_('Parent VM of assigned interface (if any)')
) )
interface = CSVModelChoiceField( interface = CSVModelChoiceField(
label=_('Interface'),
queryset=Interface.objects.none(), # Can also refer to VMInterface queryset=Interface.objects.none(), # Can also refer to VMInterface
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned interface') help_text=_('Assigned interface')
) )
is_primary = forms.BooleanField( is_primary = forms.BooleanField(
label=_('Is primary'),
help_text=_('Make this the primary IP for the assigned device'), help_text=_('Make this the primary IP for the assigned device'),
required=False required=False
) )
@ -321,11 +348,11 @@ class IPAddressImportForm(NetBoxModelImportForm):
# Validate is_primary # Validate is_primary
if is_primary and not device and not virtual_machine: if is_primary and not device and not virtual_machine:
raise forms.ValidationError({ 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: if is_primary and not interface:
raise forms.ValidationError({ 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): def save(self, *args, **kwargs):
@ -350,9 +377,11 @@ class IPAddressImportForm(NetBoxModelImportForm):
class FHRPGroupImportForm(NetBoxModelImportForm): class FHRPGroupImportForm(NetBoxModelImportForm):
protocol = CSVChoiceField( protocol = CSVChoiceField(
label=_('Protocol'),
choices=FHRPGroupProtocolChoices choices=FHRPGroupProtocolChoices
) )
auth_type = CSVChoiceField( auth_type = CSVChoiceField(
label=_('Auth type'),
choices=FHRPGroupAuthTypeChoices, choices=FHRPGroupAuthTypeChoices,
required=False required=False
) )
@ -373,13 +402,13 @@ class VLANGroupImportForm(NetBoxModelImportForm):
min_value=VLAN_VID_MIN, min_value=VLAN_VID_MIN,
max_value=VLAN_VID_MAX, max_value=VLAN_VID_MAX,
required=False, 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( max_vid = forms.IntegerField(
min_value=VLAN_VID_MIN, min_value=VLAN_VID_MIN,
max_value=VLAN_VID_MAX, max_value=VLAN_VID_MAX,
required=False, 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: class Meta:
@ -392,28 +421,33 @@ class VLANGroupImportForm(NetBoxModelImportForm):
class VLANImportForm(NetBoxModelImportForm): class VLANImportForm(NetBoxModelImportForm):
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned site') help_text=_('Assigned site')
) )
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=VLANGroup.objects.all(), queryset=VLANGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned VLAN group') help_text=_('Assigned VLAN group')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=VLANStatusChoices, choices=VLANStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -427,6 +461,7 @@ class VLANImportForm(NetBoxModelImportForm):
class ServiceTemplateImportForm(NetBoxModelImportForm): class ServiceTemplateImportForm(NetBoxModelImportForm):
protocol = CSVChoiceField( protocol = CSVChoiceField(
label=_('Protocol'),
choices=ServiceProtocolChoices, choices=ServiceProtocolChoices,
help_text=_('IP protocol') help_text=_('IP protocol')
) )
@ -438,18 +473,21 @@ class ServiceTemplateImportForm(NetBoxModelImportForm):
class ServiceImportForm(NetBoxModelImportForm): class ServiceImportForm(NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Required if not assigned to a VM') help_text=_('Required if not assigned to a VM')
) )
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Required if not assigned to a device') help_text=_('Required if not assigned to a device')
) )
protocol = CSVChoiceField( protocol = CSVChoiceField(
label=_('Protocol'),
choices=ServiceProtocolChoices, choices=ServiceProtocolChoices,
help_text=_('IP protocol') help_text=_('IP protocol')
) )
@ -461,11 +499,13 @@ class ServiceImportForm(NetBoxModelImportForm):
class L2VPNImportForm(NetBoxModelImportForm): class L2VPNImportForm(NetBoxModelImportForm):
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
) )
type = CSVChoiceField( type = CSVChoiceField(
label=_('Type'),
choices=L2VPNTypeChoices, choices=L2VPNTypeChoices,
help_text=_('L2VPN type') help_text=_('L2VPN type')
) )
@ -484,24 +524,28 @@ class L2VPNTerminationImportForm(NetBoxModelImportForm):
label=_('L2VPN'), label=_('L2VPN'),
) )
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent device (for interface)') help_text=_('Parent device (for interface)')
) )
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent virtual machine (for interface)') help_text=_('Parent virtual machine (for interface)')
) )
interface = CSVModelChoiceField( interface = CSVModelChoiceField(
label=_('Interface'),
queryset=Interface.objects.none(), # Can also refer to VMInterface queryset=Interface.objects.none(), # Can also refer to VMInterface
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned interface (device or VM)') help_text=_('Assigned interface (device or VM)')
) )
vlan = CSVModelChoiceField( vlan = CSVModelChoiceField(
label=_('VLAN'),
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -531,10 +575,10 @@ class L2VPNTerminationImportForm(NetBoxModelImportForm):
super().clean() super().clean()
if self.cleaned_data.get('device') and self.cleaned_data.get('virtual_machine'): 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')): 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'): 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') self.instance.assigned_object = self.cleaned_data.get('interface') or self.cleaned_data.get('vlan')

View File

@ -1,6 +1,6 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType 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 dcim.models import Location, Rack, Region, Site, SiteGroup, Device
from ipam.choices import * from ipam.choices import *
@ -47,8 +47,8 @@ class VRFFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VRF model = VRF
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Route Targets', ('import_target_id', 'export_target_id')), (_('Route Targets'), ('import_target_id', 'export_target_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
import_target_id = DynamicModelMultipleChoiceField( import_target_id = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
@ -67,8 +67,8 @@ class RouteTargetFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = RouteTarget model = RouteTarget
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('VRF', ('importing_vrf_id', 'exporting_vrf_id')), (_('VRF'), ('importing_vrf_id', 'exporting_vrf_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
importing_vrf_id = DynamicModelMultipleChoiceField( importing_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@ -99,8 +99,8 @@ class AggregateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Aggregate model = Aggregate
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('family', 'rir_id')), (_('Attributes'), ('family', 'rir_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
family = forms.ChoiceField( family = forms.ChoiceField(
required=False, required=False,
@ -119,8 +119,8 @@ class ASNRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = ASNRange model = ASNRange
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Range', ('rir_id', 'start', 'end')), (_('Range'), ('rir_id', 'start', 'end')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
rir_id = DynamicModelMultipleChoiceField( rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
@ -128,9 +128,11 @@ class ASNRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('RIR') label=_('RIR')
) )
start = forms.IntegerField( start = forms.IntegerField(
label=_('Start'),
required=False required=False
) )
end = forms.IntegerField( end = forms.IntegerField(
label=_('End'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -140,8 +142,8 @@ class ASNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = ASN model = ASN
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Assignment', ('rir_id', 'site_id')), (_('Assignment'), ('rir_id', 'site_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
rir_id = DynamicModelMultipleChoiceField( rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
@ -165,10 +167,10 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = Prefix model = Prefix
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Addressing', ('within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized')), (_('Addressing'), ('within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized')),
('VRF', ('vrf_id', 'present_in_vrf_id')), (_('VRF'), ('vrf_id', 'present_in_vrf_id')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
mask_length__lte = forms.IntegerField( mask_length__lte = forms.IntegerField(
widget=forms.HiddenInput() widget=forms.HiddenInput()
@ -204,6 +206,7 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Present in VRF') label=_('Present in VRF')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=PrefixStatusChoices, choices=PrefixStatusChoices,
required=False required=False
) )
@ -253,8 +256,8 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPRange model = IPRange
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attriubtes', ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')), (_('Attriubtes'), ('family', 'vrf_id', 'status', 'role_id', 'mark_utilized')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
family = forms.ChoiceField( family = forms.ChoiceField(
required=False, required=False,
@ -268,6 +271,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
null_option='Global' null_option='Global'
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=IPRangeStatusChoices, choices=IPRangeStatusChoices,
required=False required=False
) )
@ -291,10 +295,10 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = IPAddress model = IPAddress
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface')), (_('Attributes'), ('parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface')),
('VRF', ('vrf_id', 'present_in_vrf_id')), (_('VRF'), ('vrf_id', 'present_in_vrf_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Device/VM', ('device_id', 'virtual_machine_id')), (_('Device/VM'), ('device_id', 'virtual_machine_id')),
) )
parent = forms.CharField( parent = forms.CharField(
required=False, required=False,
@ -337,10 +341,12 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Assigned VM'), label=_('Assigned VM'),
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=IPAddressStatusChoices, choices=IPAddressStatusChoices,
required=False required=False
) )
role = forms.MultipleChoiceField( role = forms.MultipleChoiceField(
label=_('Role'),
choices=IPAddressRoleChoices, choices=IPAddressRoleChoices,
required=False required=False
) )
@ -358,29 +364,31 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
model = FHRPGroup model = FHRPGroup
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('name', 'protocol', 'group_id')), (_('Attributes'), ('name', 'protocol', 'group_id')),
('Authentication', ('auth_type', 'auth_key')), (_('Authentication'), ('auth_type', 'auth_key')),
) )
name = forms.CharField( name = forms.CharField(
label=_('Name'),
required=False required=False
) )
protocol = forms.MultipleChoiceField( protocol = forms.MultipleChoiceField(
label=_('Protocol'),
choices=FHRPGroupProtocolChoices, choices=FHRPGroupProtocolChoices,
required=False required=False
) )
group_id = forms.IntegerField( group_id = forms.IntegerField(
min_value=0, min_value=0,
required=False, required=False,
label='Group ID' label=_('Group ID')
) )
auth_type = forms.MultipleChoiceField( auth_type = forms.MultipleChoiceField(
choices=FHRPGroupAuthTypeChoices, choices=FHRPGroupAuthTypeChoices,
required=False, required=False,
label='Authentication type' label=_('Authentication type')
) )
auth_key = forms.CharField( auth_key = forms.CharField(
required=False, required=False,
label='Authentication key' label=_('Authentication key')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -388,8 +396,8 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
class VLANGroupFilterForm(NetBoxModelFilterSetForm): class VLANGroupFilterForm(NetBoxModelFilterSetForm):
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region', 'sitegroup', 'site', 'location', 'rack')), (_('Location'), ('region', 'sitegroup', 'site', 'location', 'rack')),
('VLAN ID', ('min_vid', 'max_vid')), (_('VLAN ID'), ('min_vid', 'max_vid')),
) )
model = VLANGroup model = VLANGroup
region = DynamicModelMultipleChoiceField( region = DynamicModelMultipleChoiceField(
@ -436,9 +444,9 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = VLAN model = VLAN
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Attributes', ('group_id', 'status', 'role_id', 'vid', 'l2vpn_id')), (_('Attributes'), ('group_id', 'status', 'role_id', 'vid', 'l2vpn_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
region_id = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
@ -469,6 +477,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('VLAN group') label=_('VLAN group')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=VLANStatusChoices, choices=VLANStatusChoices,
required=False required=False
) )
@ -480,7 +489,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
) )
vid = forms.IntegerField( vid = forms.IntegerField(
required=False, required=False,
label='VLAN ID' label=_('VLAN ID')
) )
l2vpn_id = DynamicModelMultipleChoiceField( l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(), queryset=L2VPN.objects.all(),
@ -494,13 +503,15 @@ class ServiceTemplateFilterForm(NetBoxModelFilterSetForm):
model = ServiceTemplate model = ServiceTemplate
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('protocol', 'port')), (_('Attributes'), ('protocol', 'port')),
) )
protocol = forms.ChoiceField( protocol = forms.ChoiceField(
label=_('Protocol'),
choices=add_blank_choice(ServiceProtocolChoices), choices=add_blank_choice(ServiceProtocolChoices),
required=False required=False
) )
port = forms.IntegerField( port = forms.IntegerField(
label=_('Port'),
required=False, required=False,
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -515,10 +526,11 @@ class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = L2VPN model = L2VPN
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('type', 'import_target_id', 'export_target_id')), (_('Attributes'), ('type', 'import_target_id', 'export_target_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
) )
type = forms.ChoiceField( type = forms.ChoiceField(
label=_('Type'),
choices=add_blank_choice(L2VPNTypeChoices), choices=add_blank_choice(L2VPNTypeChoices),
required=False required=False
) )
@ -539,14 +551,14 @@ class L2VPNTerminationFilterForm(NetBoxModelFilterSetForm):
model = L2VPNTermination model = L2VPNTermination
fieldsets = ( fieldsets = (
(None, ('filter_id', 'l2vpn_id',)), (None, ('filter_id', 'l2vpn_id',)),
('Assigned Object', ( (_('Assigned Object'), (
'assigned_object_type_id', 'region_id', 'site_id', 'device_id', 'virtual_machine_id', 'vlan_id', 'assigned_object_type_id', 'region_id', 'site_id', 'device_id', 'virtual_machine_id', 'vlan_id',
)), )),
) )
l2vpn_id = DynamicModelChoiceField( l2vpn_id = DynamicModelChoiceField(
queryset=L2VPN.objects.all(), queryset=L2VPN.objects.all(),
required=False, required=False,
label='L2VPN' label=_('L2VPN')
) )
assigned_object_type_id = ContentTypeMultipleChoiceField( assigned_object_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.filter(L2VPN_ASSIGNMENT_MODELS), queryset=ContentType.objects.filter(L2VPN_ASSIGNMENT_MODELS),

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError 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 dcim.models import Device, Interface, Location, Rack, Region, Site, SiteGroup
from ipam.choices import * from ipam.choices import *
@ -46,19 +46,21 @@ __all__ = (
class VRFForm(TenancyForm, NetBoxModelForm): class VRFForm(TenancyForm, NetBoxModelForm):
import_targets = DynamicModelMultipleChoiceField( import_targets = DynamicModelMultipleChoiceField(
label=_('Import targets'),
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
export_targets = DynamicModelMultipleChoiceField( export_targets = DynamicModelMultipleChoiceField(
label=_('Export targets'),
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('VRF', ('name', 'rd', 'enforce_unique', 'description', 'tags')), (_('VRF'), ('name', 'rd', 'enforce_unique', 'description', 'tags')),
('Route Targets', ('import_targets', 'export_targets')), (_('Route Targets'), ('import_targets', 'export_targets')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -90,7 +92,7 @@ class RIRForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('RIR', ( (_('RIR'), (
'name', 'slug', 'is_private', 'description', 'tags', 'name', 'slug', 'is_private', 'description', 'tags',
)), )),
) )
@ -110,8 +112,8 @@ class AggregateForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Aggregate', ('prefix', 'rir', 'date_added', 'description', 'tags')), (_('Aggregate'), ('prefix', 'rir', 'date_added', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -131,8 +133,8 @@ class ASNRangeForm(TenancyForm, NetBoxModelForm):
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('ASN Range', ('name', 'slug', 'rir', 'start', 'end', 'description', 'tags')), (_('ASN Range'), ('name', 'slug', 'rir', 'start', 'end', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -155,8 +157,8 @@ class ASNForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('ASN', ('asn', 'rir', 'sites', 'description', 'tags')), (_('ASN'), ('asn', 'rir', 'sites', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -184,7 +186,7 @@ class RoleForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Role', ( (_('Role'), (
'name', 'slug', 'weight', 'description', 'tags', 'name', 'slug', 'weight', 'description', 'tags',
)), )),
) )
@ -203,6 +205,7 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
label=_('VRF') label=_('VRF')
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
selector=True, selector=True,
@ -215,15 +218,16 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
label=_('VLAN'), label=_('VLAN'),
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Prefix', ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')), (_('Prefix'), ('prefix', 'status', 'vrf', 'role', 'is_pool', 'mark_utilized', 'description', 'tags')),
('Site/VLAN Assignment', ('site', 'vlan')), (_('Site/VLAN Assignment'), ('site', 'vlan')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -241,14 +245,15 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
label=_('VRF') label=_('VRF')
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('IP Range', ('vrf', 'start_address', 'end_address', 'role', 'status', 'mark_utilized', 'description', 'tags')), (_('IP Range'), ('vrf', 'start_address', 'end_address', 'role', 'status', 'mark_utilized', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -261,6 +266,7 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
class IPAddressForm(TenancyForm, NetBoxModelForm): class IPAddressForm(TenancyForm, NetBoxModelForm):
interface = DynamicModelChoiceField( interface = DynamicModelChoiceField(
label=_('Interface'),
queryset=Interface.objects.all(), queryset=Interface.objects.all(),
required=False, required=False,
selector=True, selector=True,
@ -341,13 +347,13 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
] ]
if len(selected_objects) > 1: if len(selected_objects) > 1:
raise forms.ValidationError({ 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: elif selected_objects:
assigned_object = self.cleaned_data[selected_objects[0]] 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: if self.instance.pk and self.cleaned_data['primary_for_parent'] and assigned_object != self.instance.assigned_object:
raise ValidationError( 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 self.instance.assigned_object = assigned_object
else: else:
@ -357,19 +363,21 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface') interface = self.cleaned_data.get('interface') or self.cleaned_data.get('vminterface')
if self.cleaned_data.get('primary_for_parent') and not interface: if self.cleaned_data.get('primary_for_parent') and not interface:
self.add_error( 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. # Do not allow assigning a network ID or broadcast address to an interface.
if interface and (address := self.cleaned_data.get('address')): if interface and (address := self.cleaned_data.get('address')):
if address.ip == address.network: 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): if address.version == 4 and address.prefixlen not in (31, 32):
raise ValidationError(msg) raise ValidationError(msg)
if address.version == 6 and address.prefixlen not in (127, 128): if address.version == 6 and address.prefixlen not in (127, 128):
raise ValidationError(msg) raise ValidationError(msg)
if address.version == 4 and address.ip == address.broadcast and address.prefixlen not in (31, 32): 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) raise ValidationError(msg)
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
@ -442,9 +450,9 @@ class FHRPGroupForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('FHRP Group', ('protocol', 'group_id', 'name', 'description', 'tags')), (_('FHRP Group'), ('protocol', 'group_id', 'name', 'description', 'tags')),
('Authentication', ('auth_type', 'auth_key')), (_('Authentication'), ('auth_type', 'auth_key')),
('Virtual IP Address', ('ip_vrf', 'ip_address', 'ip_status')) (_('Virtual IP Address'), ('ip_vrf', 'ip_address', 'ip_status'))
) )
class Meta: class Meta:
@ -497,6 +505,7 @@ class FHRPGroupForm(NetBoxModelForm):
class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm): class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=FHRPGroup.objects.all() queryset=FHRPGroup.objects.all()
) )
@ -514,10 +523,12 @@ class FHRPGroupAssignmentForm(BootstrapMixin, forms.ModelForm):
class VLANGroupForm(NetBoxModelForm): class VLANGroupForm(NetBoxModelForm):
scope_type = ContentTypeChoiceField( scope_type = ContentTypeChoiceField(
label=_('Scope type'),
queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES), queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
required=False required=False
) )
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -533,6 +544,7 @@ class VLANGroupForm(NetBoxModelForm):
label=_('Site group') label=_('Site group')
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -544,6 +556,7 @@ class VLANGroupForm(NetBoxModelForm):
} }
) )
location = DynamicModelChoiceField( location = DynamicModelChoiceField(
label=_('Location'),
queryset=Location.objects.all(), queryset=Location.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -554,6 +567,7 @@ class VLANGroupForm(NetBoxModelForm):
} }
) )
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -570,6 +584,7 @@ class VLANGroupForm(NetBoxModelForm):
label=_('Cluster group') label=_('Cluster group')
) )
cluster = DynamicModelChoiceField( cluster = DynamicModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -579,9 +594,9 @@ class VLANGroupForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('VLAN Group', ('name', 'slug', 'description', 'tags')), (_('VLAN Group'), ('name', 'slug', 'description', 'tags')),
('Child VLANs', ('min_vid', 'max_vid')), (_('Child VLANs'), ('min_vid', 'max_vid')),
('Scope', ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')), (_('Scope'), ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')),
) )
class Meta: class Meta:
@ -621,12 +636,14 @@ class VLANForm(TenancyForm, NetBoxModelForm):
label=_('VLAN Group') label=_('VLAN Group')
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
null_option='None', null_option='None',
selector=True selector=True
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=Role.objects.all(), queryset=Role.objects.all(),
required=False required=False
) )
@ -642,6 +659,7 @@ class VLANForm(TenancyForm, NetBoxModelForm):
class ServiceTemplateForm(NetBoxModelForm): class ServiceTemplateForm(NetBoxModelForm):
ports = NumericArrayField( ports = NumericArrayField(
label=_('Ports'),
base_field=forms.IntegerField( base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN, min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX max_value=SERVICE_PORT_MAX
@ -651,7 +669,7 @@ class ServiceTemplateForm(NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Service Template', ( (_('Service Template'), (
'name', 'protocol', 'ports', 'description', 'tags', 'name', 'protocol', 'ports', 'description', 'tags',
)), )),
) )
@ -663,16 +681,19 @@ class ServiceTemplateForm(NetBoxModelForm):
class ServiceForm(NetBoxModelForm): class ServiceForm(NetBoxModelForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
selector=True selector=True
) )
virtual_machine = DynamicModelChoiceField( virtual_machine = DynamicModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
selector=True selector=True
) )
ports = NumericArrayField( ports = NumericArrayField(
label=_('Ports'),
base_field=forms.IntegerField( base_field=forms.IntegerField(
min_value=SERVICE_PORT_MIN, min_value=SERVICE_PORT_MIN,
max_value=SERVICE_PORT_MAX max_value=SERVICE_PORT_MAX
@ -699,6 +720,7 @@ class ServiceForm(NetBoxModelForm):
class ServiceCreateForm(ServiceForm): class ServiceCreateForm(ServiceForm):
service_template = DynamicModelChoiceField( service_template = DynamicModelChoiceField(
label=_('Service template'),
queryset=ServiceTemplate.objects.all(), queryset=ServiceTemplate.objects.all(),
required=False required=False
) )
@ -739,19 +761,21 @@ class ServiceCreateForm(ServiceForm):
class L2VPNForm(TenancyForm, NetBoxModelForm): class L2VPNForm(TenancyForm, NetBoxModelForm):
slug = SlugField() slug = SlugField()
import_targets = DynamicModelMultipleChoiceField( import_targets = DynamicModelMultipleChoiceField(
label=_('Import targets'),
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
export_targets = DynamicModelMultipleChoiceField( export_targets = DynamicModelMultipleChoiceField(
label=_('Export targets'),
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('L2VPN', ('name', 'slug', 'type', 'identifier', 'description', 'tags')), (_('L2VPN'), ('name', 'slug', 'type', 'identifier', 'description', 'tags')),
('Route Targets', ('import_targets', 'export_targets')), (_('Route Targets'), ('import_targets', 'export_targets')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -777,6 +801,7 @@ class L2VPNTerminationForm(NetBoxModelForm):
label=_('VLAN') label=_('VLAN')
) )
interface = DynamicModelChoiceField( interface = DynamicModelChoiceField(
label=_('Interface'),
queryset=Interface.objects.all(), queryset=Interface.objects.all(),
required=False, required=False,
selector=True selector=True
@ -815,8 +840,8 @@ class L2VPNTerminationForm(NetBoxModelForm):
vlan = self.cleaned_data.get('vlan') vlan = self.cleaned_data.get('vlan')
if not (interface or vminterface or 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: 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 self.instance.assigned_object = interface or vminterface or vlan

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.db.models import Q 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.choices import CustomFieldFilterLogicChoices, CustomFieldTypeChoices, CustomFieldVisibilityChoices
from extras.forms.mixins import CustomFieldsMixin, SavedFiltersMixin from extras.forms.mixins import CustomFieldsMixin, SavedFiltersMixin
@ -28,7 +28,8 @@ class NetBoxModelForm(BootstrapMixin, CustomFieldsMixin, forms.ModelForm):
fieldsets = () fieldsets = ()
tags = DynamicModelMultipleChoiceField( tags = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False,
label=_('Tags'),
) )
def __init__(self, *args, **kwargs): 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. Base form for creating a NetBox objects from CSV data. Used for bulk importing.
""" """
id = forms.IntegerField( id = forms.IntegerField(
label=_('Id'),
required=False, required=False,
help_text='Numeric ID of an existing object to update (if not creating a new object)' help_text='Numeric ID of an existing object to update (if not creating a new object)'
) )
tags = CSVModelMultipleChoiceField( tags = CSVModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False, required=False,
to_field_name='slug', to_field_name='slug',
@ -109,10 +112,12 @@ class NetBoxModelBulkEditForm(BootstrapMixin, CustomFieldsMixin, forms.Form):
widget=forms.MultipleHiddenInput widget=forms.MultipleHiddenInput
) )
add_tags = DynamicModelMultipleChoiceField( add_tags = DynamicModelMultipleChoiceField(
label=_('Add tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False
) )
remove_tags = DynamicModelMultipleChoiceField( remove_tags = DynamicModelMultipleChoiceField(
label=_('Remove tags'),
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
required=False required=False
) )

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelBulkEditForm from netbox.forms import NetBoxModelBulkEditForm
from tenancy.choices import ContactPriorityChoices from tenancy.choices import ContactPriorityChoices
@ -22,10 +23,12 @@ __all__ = (
class TenantGroupBulkEditForm(NetBoxModelBulkEditForm): class TenantGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -36,6 +39,7 @@ class TenantGroupBulkEditForm(NetBoxModelBulkEditForm):
class TenantBulkEditForm(NetBoxModelBulkEditForm): class TenantBulkEditForm(NetBoxModelBulkEditForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False required=False
) )
@ -53,10 +57,12 @@ class TenantBulkEditForm(NetBoxModelBulkEditForm):
class ContactGroupBulkEditForm(NetBoxModelBulkEditForm): class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Desciption'),
max_length=200, max_length=200,
required=False required=False
) )
@ -70,6 +76,7 @@ class ContactGroupBulkEditForm(NetBoxModelBulkEditForm):
class ContactRoleBulkEditForm(NetBoxModelBulkEditForm): class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -83,34 +90,39 @@ class ContactRoleBulkEditForm(NetBoxModelBulkEditForm):
class ContactBulkEditForm(NetBoxModelBulkEditForm): class ContactBulkEditForm(NetBoxModelBulkEditForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False required=False
) )
title = forms.CharField( title = forms.CharField(
label=_('Title'),
max_length=100, max_length=100,
required=False required=False
) )
phone = forms.CharField( phone = forms.CharField(
label=_('Phone'),
max_length=50, max_length=50,
required=False required=False
) )
email = forms.EmailField( email = forms.EmailField(
label=_('Email'),
required=False required=False
) )
address = forms.CharField( address = forms.CharField(
label=_('Address'),
max_length=200, max_length=200,
required=False required=False
) )
link = forms.URLField( link = forms.URLField(
label=_('Link'),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = Contact model = Contact
fieldsets = ( fieldsets = (
@ -121,14 +133,17 @@ class ContactBulkEditForm(NetBoxModelBulkEditForm):
class ContactAssignmentBulkEditForm(NetBoxModelBulkEditForm): class ContactAssignmentBulkEditForm(NetBoxModelBulkEditForm):
contact = DynamicModelChoiceField( contact = DynamicModelChoiceField(
label=_('Contact'),
queryset=Contact.objects.all(), queryset=Contact.objects.all(),
required=False required=False
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=ContactRole.objects.all(), queryset=ContactRole.objects.all(),
required=False required=False
) )
priority = forms.ChoiceField( priority = forms.ChoiceField(
label=_('Priority'),
choices=add_blank_choice(ContactPriorityChoices), choices=add_blank_choice(ContactPriorityChoices),
required=False required=False
) )

View File

@ -1,5 +1,6 @@
from django.contrib.contenttypes.models import ContentType 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 netbox.forms import NetBoxModelImportForm
from tenancy.models import * from tenancy.models import *
from utilities.forms.fields import CSVContentTypeField, CSVModelChoiceField, SlugField from utilities.forms.fields import CSVContentTypeField, CSVModelChoiceField, SlugField
@ -20,6 +21,7 @@ __all__ = (
class TenantGroupImportForm(NetBoxModelImportForm): class TenantGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -35,6 +37,7 @@ class TenantGroupImportForm(NetBoxModelImportForm):
class TenantImportForm(NetBoxModelImportForm): class TenantImportForm(NetBoxModelImportForm):
slug = SlugField() slug = SlugField()
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -52,6 +55,7 @@ class TenantImportForm(NetBoxModelImportForm):
class ContactGroupImportForm(NetBoxModelImportForm): class ContactGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -74,6 +78,7 @@ class ContactRoleImportForm(NetBoxModelImportForm):
class ContactImportForm(NetBoxModelImportForm): class ContactImportForm(NetBoxModelImportForm):
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',

View File

@ -1,6 +1,6 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType 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 extras.utils import FeatureQuery
from netbox.forms import NetBoxModelFilterSetForm from netbox.forms import NetBoxModelFilterSetForm
@ -84,7 +84,7 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm):
model = ContactAssignment model = ContactAssignment
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id')), (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( content_type_id = ContentTypeMultipleChoiceField(
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
@ -108,6 +108,7 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm):
label=_('Role') label=_('Role')
) )
priority = forms.MultipleChoiceField( priority = forms.MultipleChoiceField(
label=_('Priority'),
choices=ContactPriorityChoices, choices=ContactPriorityChoices,
required=False required=False
) )

View File

@ -1,5 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy as _
from tenancy.models import * from tenancy.models import *
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
@ -13,6 +13,7 @@ __all__ = (
class TenancyForm(forms.Form): class TenancyForm(forms.Form):
tenant_group = DynamicModelChoiceField( tenant_group = DynamicModelChoiceField(
label=_('Tenant group'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False, required=False,
null_option='None', null_option='None',
@ -21,6 +22,7 @@ class TenancyForm(forms.Form):
} }
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
query_params={ query_params={

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
from netbox.forms import NetBoxModelForm from netbox.forms import NetBoxModelForm
from tenancy.models import * from tenancy.models import *
@ -21,13 +22,14 @@ __all__ = (
class TenantGroupForm(NetBoxModelForm): class TenantGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Tenant Group', ( (_('Tenant Group'), (
'parent', 'name', 'slug', 'description', 'tags', 'parent', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -42,13 +44,14 @@ class TenantGroupForm(NetBoxModelForm):
class TenantForm(NetBoxModelForm): class TenantForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Tenant', ('name', 'slug', 'group', 'description', 'tags')), (_('Tenant'), ('name', 'slug', 'group', 'description', 'tags')),
) )
class Meta: class Meta:
@ -64,13 +67,14 @@ class TenantForm(NetBoxModelForm):
class ContactGroupForm(NetBoxModelForm): class ContactGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Contact Group', ( (_('Contact Group'), (
'parent', 'name', 'slug', 'description', 'tags', 'parent', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -84,7 +88,7 @@ class ContactRoleForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Contact Role', ( (_('Contact Role'), (
'name', 'slug', 'description', 'tags', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -96,13 +100,14 @@ class ContactRoleForm(NetBoxModelForm):
class ContactForm(NetBoxModelForm): class ContactForm(NetBoxModelForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False required=False
) )
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Contact', ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')), (_('Contact'), ('group', 'name', 'title', 'phone', 'email', 'address', 'link', 'description', 'tags')),
) )
class Meta: class Meta:
@ -117,6 +122,7 @@ class ContactForm(NetBoxModelForm):
class ContactAssignmentForm(BootstrapMixin, forms.ModelForm): class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
required=False, required=False,
initial_params={ initial_params={
@ -124,12 +130,14 @@ class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
} }
) )
contact = DynamicModelChoiceField( contact = DynamicModelChoiceField(
label=_('Contact'),
queryset=Contact.objects.all(), queryset=Contact.objects.all(),
query_params={ query_params={
'group_id': '$group' 'group_id': '$group'
} }
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=ContactRole.objects.all() queryset=ContactRole.objects.all()
) )

View File

@ -66,7 +66,6 @@ class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMe
) )
# List of clearable preferences # List of clearable preferences
pk = forms.MultipleChoiceField( pk = forms.MultipleChoiceField(
label=_('Pk'),
choices=[], choices=[],
required=False required=False
) )

View File

@ -1,5 +1,6 @@
from django import forms from django import forms
from django.contrib.postgres.forms import SimpleArrayField from django.contrib.postgres.forms import SimpleArrayField
from django.utils.translation import gettext_lazy as _
from ..utils import parse_numeric_range from ..utils import parse_numeric_range
@ -12,8 +13,9 @@ class NumericArrayField(SimpleArrayField):
def clean(self, value): def clean(self, value):
if value and not self.to_python(value): if value and not self.to_python(value):
raise forms.ValidationError(f'Invalid list ({value}). ' raise forms.ValidationError(
f'Must be numeric and ranges must be in ascending order') _("Invalid list ({value}). Must be numeric and ranges must be in ascending order.").format(value=value)
)
return super().clean(value) return super().clean(value)
def to_python(self, value): def to_python(self, value):

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext_lazy as _
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import Q from django.db.models import Q
@ -40,7 +41,7 @@ class CSVMultipleChoiceField(CSVChoicesMixin, forms.MultipleChoiceField):
if not value: if not value:
return [] return []
if not isinstance(value, str): 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(',') return value.split(',')
@ -53,7 +54,7 @@ class CSVModelChoiceField(forms.ModelChoiceField):
Extends Django's `ModelChoiceField` to provide additional validation for CSV values. Extends Django's `ModelChoiceField` to provide additional validation for CSV values.
""" """
default_error_messages = { default_error_messages = {
'invalid_choice': 'Object not found: %(value)s', 'invalid_choice': _('Object not found: %(value)s'),
} }
def to_python(self, value): def to_python(self, value):
@ -61,7 +62,7 @@ class CSVModelChoiceField(forms.ModelChoiceField):
return super().to_python(value) return super().to_python(value)
except MultipleObjectsReturned: except MultipleObjectsReturned:
raise forms.ValidationError( 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. Extends Django's `ModelMultipleChoiceField` to support comma-separated values.
""" """
default_error_messages = { default_error_messages = {
'invalid_choice': 'Object not found: %(value)s', 'invalid_choice': _('Object not found: %(value)s'),
} }
def clean(self, value): def clean(self, value):
@ -93,11 +94,11 @@ class CSVContentTypeField(CSVModelChoiceField):
try: try:
app_label, model = value.split('.') app_label, model = value.split('.')
except ValueError: except ValueError:
raise forms.ValidationError(f'Object type must be specified as "<app>.<model>"') raise forms.ValidationError(_('Object type must be specified as "<app>.<model>"'))
try: try:
return self.queryset.get(app_label=app_label, model=model) return self.queryset.get(app_label=app_label, model=model)
except ObjectDoesNotExist: except ObjectDoesNotExist:
raise forms.ValidationError(f'Invalid object type') raise forms.ValidationError(_('Invalid object type'))
class CSVMultipleContentTypeField(forms.ModelMultipleChoiceField): class CSVMultipleContentTypeField(forms.ModelMultipleChoiceField):

View File

@ -1,7 +1,7 @@
import re import re
from django import forms 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.constants import *
from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern from utilities.forms.utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
@ -21,10 +21,10 @@ class ExpandableNameField(forms.CharField):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if not self.help_text: if not self.help_text:
self.help_text = """ self.help_text = _(
Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range "Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range are "
are not supported (example: <code>[ge,xe]-0/0/[0-9]</code>). "not supported (example: <code>[ge,xe]-0/0/[0-9]</code>)."
""" )
def to_python(self, value): def to_python(self, value):
if not value: if not value:

View File

@ -4,7 +4,7 @@ from django import forms
from django.db.models import Count from django.db.models import Count
from django.forms.fields import JSONField as _JSONField, InvalidJSONInput from django.forms.fields import JSONField as _JSONField, InvalidJSONInput
from django.templatetags.static import static 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 netaddr import AddrFormatError, EUI
from utilities.forms import widgets 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`. A textarea with support for Markdown rendering. Exists mostly just to add a standard `help_text`.
""" """
widget = widgets.MarkdownWidget widget = widgets.MarkdownWidget
help_text = f""" label = _('Comments')
<i class="mdi mdi-information-outline"></i> help_text = _(
<a href="{static('docs/reference/markdown/')}" target="_blank" tabindex="-1"> '<i class="mdi mdi-information-outline"></i> '
Markdown</a> syntax is supported '<a href="{url}" target="_blank" tabindex="-1">Markdown</a> syntax is supported'
""" ).format(url=static('docs/reference/markdown/'))
def __init__(self, *, help_text=help_text, required=False, **kwargs): def __init__(self, *, label=label, help_text=help_text, required=False, **kwargs):
super().__init__(help_text=help_text, required=required, **kwargs) super().__init__(label=label, help_text=help_text, required=required, **kwargs)
class SlugField(forms.SlugField): 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 slug_source: Name of the form field from which the slug value will be derived
""" """
widget = widgets.SlugWidget widget = widgets.SlugWidget
label = _('Slug')
help_text = _("URL-friendly unique shorthand") help_text = _("URL-friendly unique shorthand")
def __init__(self, *, slug_source='name', help_text=help_text, **kwargs): def __init__(self, *, slug_source='name', label=label, help_text=help_text, **kwargs):
super().__init__(help_text=help_text, **kwargs) super().__init__(label=label, help_text=help_text, **kwargs)
self.widget.attrs['slug-source'] = slug_source self.widget.attrs['slug-source'] = slug_source
@ -77,7 +78,7 @@ class TagFilterField(forms.MultipleChoiceField):
] ]
# Choices are fetched each time the form is initialized # 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): class LaxURLField(forms.URLField):
@ -113,7 +114,7 @@ class MACAddressField(forms.Field):
""" """
widget = forms.CharField widget = forms.CharField
default_error_messages = { 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): def to_python(self, value):

View File

@ -1,5 +1,5 @@
from django import forms 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 import BootstrapMixin, form_from_model
from utilities.forms.fields import ExpandableNameField from utilities.forms.fields import ExpandableNameField

View File

@ -1,5 +1,5 @@
from django import forms 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.choices import InterfaceModeChoices
from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN from dcim.constants import INTERFACE_MTU_MAX, INTERFACE_MTU_MIN
@ -25,6 +25,7 @@ __all__ = (
class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm): class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -38,6 +39,7 @@ class ClusterTypeBulkEditForm(NetBoxModelBulkEditForm):
class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm): class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -51,31 +53,38 @@ class ClusterGroupBulkEditForm(NetBoxModelBulkEditForm):
class ClusterBulkEditForm(NetBoxModelBulkEditForm): class ClusterBulkEditForm(NetBoxModelBulkEditForm):
type = DynamicModelChoiceField( type = DynamicModelChoiceField(
label=_('Type'),
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
required=False required=False
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
required=False required=False
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(ClusterStatusChoices), choices=add_blank_choice(ClusterStatusChoices),
required=False, required=False,
initial='' initial=''
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
) )
site_group = DynamicModelChoiceField( site_group = DynamicModelChoiceField(
label=_('Site group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False, required=False,
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -84,17 +93,16 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
description = forms.CharField( description = forms.CharField(
label=_('Site'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = Cluster model = Cluster
fieldsets = ( fieldsets = (
(None, ('type', 'group', 'status', 'tenant', 'description')), (None, ('type', 'group', 'status', 'tenant', 'description')),
('Site', ('region', 'site_group', 'site')), (_('Site'), ('region', 'site_group', 'site')),
) )
nullable_fields = ( nullable_fields = (
'group', 'site', 'tenant', 'description', 'comments', 'group', 'site', 'tenant', 'description', 'comments',
@ -103,15 +111,18 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm): class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(VirtualMachineStatusChoices), choices=add_blank_choice(VirtualMachineStatusChoices),
required=False, required=False,
initial='', initial='',
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False required=False
) )
cluster = DynamicModelChoiceField( cluster = DynamicModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -119,6 +130,7 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -126,6 +138,7 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=DeviceRole.objects.filter( queryset=DeviceRole.objects.filter(
vm_role=True vm_role=True
), ),
@ -135,10 +148,12 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
} }
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
platform = DynamicModelChoiceField( platform = DynamicModelChoiceField(
label=_('Platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False required=False
) )
@ -155,17 +170,16 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
label=_('Disk (GB)') label=_('Disk (GB)')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label=_('Comments')
)
model = VirtualMachine model = VirtualMachine
fieldsets = ( fieldsets = (
(None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description')), (None, ('site', 'cluster', 'device', 'status', 'role', 'tenant', 'platform', 'description')),
('Resources', ('vcpus', 'memory', 'disk')) (_('Resources'), ('vcpus', 'memory', 'disk'))
) )
nullable_fields = ( nullable_fields = (
'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments', 'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments',
@ -174,20 +188,24 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm): class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
virtual_machine = forms.ModelChoiceField( virtual_machine = forms.ModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
disabled=True, disabled=True,
widget=forms.HiddenInput() widget=forms.HiddenInput()
) )
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=VMInterface.objects.all(), queryset=VMInterface.objects.all(),
required=False required=False
) )
bridge = DynamicModelChoiceField( bridge = DynamicModelChoiceField(
label=_('Bridge'),
queryset=VMInterface.objects.all(), queryset=VMInterface.objects.all(),
required=False required=False
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=BulkEditNullBooleanSelect() widget=BulkEditNullBooleanSelect()
) )
@ -198,10 +216,12 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
label=_('MTU') label=_('MTU')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=100, max_length=100,
required=False required=False
) )
mode = forms.ChoiceField( mode = forms.ChoiceField(
label=_('Mode'),
choices=add_blank_choice(InterfaceModeChoices), choices=add_blank_choice(InterfaceModeChoices),
required=False required=False
) )
@ -235,8 +255,8 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
model = VMInterface model = VMInterface
fieldsets = ( fieldsets = (
(None, ('mtu', 'enabled', 'vrf', 'description')), (None, ('mtu', 'enabled', 'vrf', 'description')),
('Related Interfaces', ('parent', 'bridge')), (_('Related Interfaces'), ('parent', 'bridge')),
('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')), (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
) )
nullable_fields = ( nullable_fields = (
'parent', 'bridge', 'mtu', 'vrf', 'description', 'parent', 'bridge', 'mtu', 'vrf', 'description',

View File

@ -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.choices import InterfaceModeChoices
from dcim.models import Device, DeviceRole, Platform, Site from dcim.models import Device, DeviceRole, Platform, Site
@ -36,27 +36,32 @@ class ClusterGroupImportForm(NetBoxModelImportForm):
class ClusterImportForm(NetBoxModelImportForm): class ClusterImportForm(NetBoxModelImportForm):
type = CSVModelChoiceField( type = CSVModelChoiceField(
label=_('Type'),
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
to_field_name='name', to_field_name='name',
help_text=_('Type of cluster') help_text=_('Type of cluster')
) )
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned cluster group') help_text=_('Assigned cluster group')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=ClusterStatusChoices, choices=ClusterStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned site') help_text=_('Assigned site')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
@ -70,28 +75,33 @@ class ClusterImportForm(NetBoxModelImportForm):
class VirtualMachineImportForm(NetBoxModelImportForm): class VirtualMachineImportForm(NetBoxModelImportForm):
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=VirtualMachineStatusChoices, choices=VirtualMachineStatusChoices,
help_text=_('Operational status') help_text=_('Operational status')
) )
site = CSVModelChoiceField( site = CSVModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned site') help_text=_('Assigned site')
) )
cluster = CSVModelChoiceField( cluster = CSVModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned cluster') help_text=_('Assigned cluster')
) )
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
to_field_name='name', to_field_name='name',
required=False, required=False,
help_text=_('Assigned device within cluster') help_text=_('Assigned device within cluster')
) )
role = CSVModelChoiceField( role = CSVModelChoiceField(
label=_('Role'),
queryset=DeviceRole.objects.filter( queryset=DeviceRole.objects.filter(
vm_role=True vm_role=True
), ),
@ -100,12 +110,14 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
help_text=_('Functional role') help_text=_('Functional role')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
platform = CSVModelChoiceField( platform = CSVModelChoiceField(
label=_('Platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -122,27 +134,32 @@ class VirtualMachineImportForm(NetBoxModelImportForm):
class VMInterfaceImportForm(NetBoxModelImportForm): class VMInterfaceImportForm(NetBoxModelImportForm):
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
to_field_name='name' to_field_name='name'
) )
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=VMInterface.objects.all(), queryset=VMInterface.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Parent interface') help_text=_('Parent interface')
) )
bridge = CSVModelChoiceField( bridge = CSVModelChoiceField(
label=_('Bridge'),
queryset=VMInterface.objects.all(), queryset=VMInterface.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Bridged interface') help_text=_('Bridged interface')
) )
mode = CSVChoiceField( mode = CSVChoiceField(
label=_('Mode'),
choices=InterfaceModeChoices, choices=InterfaceModeChoices,
required=False, required=False,
help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)') help_text=_('IEEE 802.1Q operational mode (for L2 interfaces)')
) )
vrf = CSVModelChoiceField( vrf = CSVModelChoiceField(
label=_('VRF'),
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
to_field_name='rd', to_field_name='rd',

View File

@ -1,5 +1,5 @@
from django import forms 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 dcim.models import Device, DeviceRole, Platform, Region, Site, SiteGroup
from extras.forms import LocalConfigContextFilterForm from extras.forms import LocalConfigContextFilterForm
@ -30,7 +30,7 @@ class ClusterGroupFilterForm(ContactModelFilterForm, NetBoxModelFilterSetForm):
tag = TagFilterField(model) tag = TagFilterField(model)
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (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 model = Cluster
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('group_id', 'type_id', 'status')), (_('Attributes'), ('group_id', 'type_id', 'status')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
type_id = DynamicModelMultipleChoiceField( type_id = DynamicModelMultipleChoiceField(
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
@ -54,6 +54,7 @@ class ClusterFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
label=_('Region') label=_('Region')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=ClusterStatusChoices, choices=ClusterStatusChoices,
required=False required=False
) )
@ -90,11 +91,11 @@ class VirtualMachineFilterForm(
model = VirtualMachine model = VirtualMachine
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Cluster', ('cluster_group_id', 'cluster_type_id', 'cluster_id', 'device_id')), (_('Cluster'), ('cluster_group_id', 'cluster_type_id', 'cluster_id', 'device_id')),
('Location', ('region_id', 'site_group_id', 'site_id')), (_('Location'), ('region_id', 'site_group_id', 'site_id')),
('Attributes', ('status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data')), (_('Attributes'), ('status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role', 'contact_group')), (_('Contacts'), ('contact', 'contact_role', 'contact_group')),
) )
cluster_group_id = DynamicModelMultipleChoiceField( cluster_group_id = DynamicModelMultipleChoiceField(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
@ -148,6 +149,7 @@ class VirtualMachineFilterForm(
label=_('Role') label=_('Role')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
label=_('Status'),
choices=VirtualMachineStatusChoices, choices=VirtualMachineStatusChoices,
required=False required=False
) )
@ -175,8 +177,8 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
model = VMInterface model = VMInterface
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Virtual Machine', ('cluster_id', 'virtual_machine_id')), (_('Virtual Machine'), ('cluster_id', 'virtual_machine_id')),
('Attributes', ('enabled', 'mac_address', 'vrf_id', 'l2vpn_id')), (_('Attributes'), ('enabled', 'mac_address', 'vrf_id', 'l2vpn_id')),
) )
cluster_id = DynamicModelMultipleChoiceField( cluster_id = DynamicModelMultipleChoiceField(
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
@ -192,6 +194,7 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
label=_('Virtual machine') label=_('Virtual machine')
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
label=_('Enabled'),
required=False, required=False,
widget=forms.Select( widget=forms.Select(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
@ -199,12 +202,12 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
) )
mac_address = forms.CharField( mac_address = forms.CharField(
required=False, required=False,
label='MAC address' label=_('MAC address')
) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='VRF' label=_('VRF')
) )
l2vpn_id = DynamicModelMultipleChoiceField( l2vpn_id = DynamicModelMultipleChoiceField(
queryset=L2VPN.objects.all(), queryset=L2VPN.objects.all(),

View File

@ -1,7 +1,7 @@
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError 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.forms.common import InterfaceCommonForm
from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site, SiteGroup from dcim.models import Device, DeviceRole, Platform, Rack, Region, Site, SiteGroup
@ -30,7 +30,7 @@ class ClusterTypeForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Cluster Type', ( (_('Cluster Type'), (
'name', 'slug', 'description', 'tags', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -46,7 +46,7 @@ class ClusterGroupForm(NetBoxModelForm):
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Cluster Group', ( (_('Cluster Group'), (
'name', 'slug', 'description', 'tags', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -60,13 +60,16 @@ class ClusterGroupForm(NetBoxModelForm):
class ClusterForm(TenancyForm, NetBoxModelForm): class ClusterForm(TenancyForm, NetBoxModelForm):
type = DynamicModelChoiceField( type = DynamicModelChoiceField(
label=_('Type'),
queryset=ClusterType.objects.all() queryset=ClusterType.objects.all()
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
required=False required=False
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
selector=True selector=True
@ -74,8 +77,8 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Cluster', ('name', 'type', 'group', 'site', 'status', 'description', 'tags')), (_('Cluster'), ('name', 'type', 'group', 'site', 'status', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
) )
class Meta: class Meta:
@ -87,16 +90,19 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
class ClusterAddDevicesForm(BootstrapMixin, forms.Form): class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
label=_('Region'),
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
null_option='None' null_option='None'
) )
site_group = DynamicModelChoiceField( site_group = DynamicModelChoiceField(
label=_('Site group'),
queryset=SiteGroup.objects.all(), queryset=SiteGroup.objects.all(),
required=False, required=False,
null_option='None' null_option='None'
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -105,6 +111,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
} }
) )
rack = DynamicModelChoiceField( rack = DynamicModelChoiceField(
label=_('Rack'),
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
null_option='None', null_option='None',
@ -113,6 +120,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
} }
) )
devices = DynamicModelMultipleChoiceField( devices = DynamicModelMultipleChoiceField(
label=_('Devices'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
query_params={ query_params={
'site_id': '$site', 'site_id': '$site',
@ -142,7 +150,7 @@ class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
for device in self.cleaned_data.get('devices', []): for device in self.cleaned_data.get('devices', []):
if device.site != self.cluster.site: if device.site != self.cluster.site:
raise ValidationError({ 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 device, device.site, self.cluster.site
) )
}) })
@ -157,10 +165,12 @@ class ClusterRemoveDevicesForm(ConfirmationForm):
class VirtualMachineForm(TenancyForm, NetBoxModelForm): class VirtualMachineForm(TenancyForm, NetBoxModelForm):
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
label=_('Site'),
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False required=False
) )
cluster = DynamicModelChoiceField( cluster = DynamicModelChoiceField(
label=_('Cluster'),
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
selector=True, selector=True,
@ -169,6 +179,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
} }
) )
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -178,6 +189,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
help_text=_("Optionally pin this VM to a specific host device within the cluster") help_text=_("Optionally pin this VM to a specific host device within the cluster")
) )
role = DynamicModelChoiceField( role = DynamicModelChoiceField(
label=_('Role'),
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
required=False, required=False,
query_params={ query_params={
@ -185,6 +197,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
} }
) )
platform = DynamicModelChoiceField( platform = DynamicModelChoiceField(
label=_('Platform'),
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
required=False required=False
) )
@ -195,12 +208,12 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Virtual Machine', ('name', 'role', 'status', 'description', 'tags')), (_('Virtual Machine'), ('name', 'role', 'status', 'description', 'tags')),
('Site/Cluster', ('site', 'cluster', 'device')), (_('Site/Cluster'), ('site', 'cluster', 'device')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
('Management', ('platform', 'primary_ip4', 'primary_ip6')), (_('Management'), ('platform', 'primary_ip4', 'primary_ip6')),
('Resources', ('vcpus', 'memory', 'disk')), (_('Resources'), ('vcpus', 'memory', 'disk')),
('Config Context', ('local_context_data',)), (_('Config Context'), ('local_context_data',)),
) )
class Meta: class Meta:
@ -253,6 +266,7 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm): class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
virtual_machine = DynamicModelChoiceField( virtual_machine = DynamicModelChoiceField(
label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
selector=True selector=True
) )
@ -302,11 +316,11 @@ class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
) )
fieldsets = ( fieldsets = (
('Interface', ('virtual_machine', 'name', 'description', 'tags')), (_('Interface'), ('virtual_machine', 'name', 'description', 'tags')),
('Addressing', ('vrf', 'mac_address')), (_('Addressing'), ('vrf', 'mac_address')),
('Operation', ('mtu', 'enabled')), (_('Operation'), ('mtu', 'enabled')),
('Related Interfaces', ('parent', 'bridge')), (_('Related Interfaces'), ('parent', 'bridge')),
('802.1Q Switching', ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')), (_('802.1Q Switching'), ('mode', 'vlan_group', 'untagged_vlan', 'tagged_vlans')),
) )
class Meta: class Meta:

View File

@ -1,3 +1,4 @@
from django.utils.translation import gettext_lazy as _
from utilities.forms.fields import ExpandableNameField from utilities.forms.fields import ExpandableNameField
from .model_forms import VMInterfaceForm from .model_forms import VMInterfaceForm
@ -7,7 +8,9 @@ __all__ = (
class VMInterfaceCreateForm(VMInterfaceForm): class VMInterfaceCreateForm(VMInterfaceForm):
name = ExpandableNameField() name = ExpandableNameField(
label=_('Name'),
)
replication_fields = ('name',) replication_fields = ('name',)
class Meta(VMInterfaceForm.Meta): class Meta(VMInterfaceForm.Meta):

View File

@ -1,5 +1,5 @@
from django import forms 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 dcim.choices import LinkStatusChoices
from ipam.models import VLAN from ipam.models import VLAN
@ -20,10 +20,12 @@ __all__ = (
class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm): class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False required=False
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
@ -37,10 +39,12 @@ class WirelessLANGroupBulkEditForm(NetBoxModelBulkEditForm):
class WirelessLANBulkEditForm(NetBoxModelBulkEditForm): class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(WirelessLANStatusChoices), choices=add_blank_choice(WirelessLANStatusChoices),
required=False required=False
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False required=False
) )
@ -55,14 +59,17 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
label=_('SSID') label=_('SSID')
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
label=_('Authentication type'),
choices=add_blank_choice(WirelessAuthTypeChoices), choices=add_blank_choice(WirelessAuthTypeChoices),
required=False required=False
) )
auth_cipher = forms.ChoiceField( auth_cipher = forms.ChoiceField(
label=_('Authentication cipher'),
choices=add_blank_choice(WirelessAuthCipherChoices), choices=add_blank_choice(WirelessAuthCipherChoices),
required=False required=False
) )
@ -71,17 +78,16 @@ class WirelessLANBulkEditForm(NetBoxModelBulkEditForm):
label=_('Pre-shared key') label=_('Pre-shared key')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = WirelessLAN model = WirelessLAN
fieldsets = ( fieldsets = (
(None, ('group', 'ssid', 'status', 'vlan', 'tenant', 'description')), (None, ('group', 'ssid', 'status', 'vlan', 'tenant', 'description')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
) )
nullable_fields = ( nullable_fields = (
'ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments', 'ssid', 'group', 'vlan', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',
@ -95,18 +101,22 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
label=_('SSID') label=_('SSID')
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
choices=add_blank_choice(LinkStatusChoices), choices=add_blank_choice(LinkStatusChoices),
required=False required=False
) )
tenant = DynamicModelChoiceField( tenant = DynamicModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False required=False
) )
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
label=_('Authentication type'),
choices=add_blank_choice(WirelessAuthTypeChoices), choices=add_blank_choice(WirelessAuthTypeChoices),
required=False required=False
) )
auth_cipher = forms.ChoiceField( auth_cipher = forms.ChoiceField(
label=_('Authentication cipher'),
choices=add_blank_choice(WirelessAuthCipherChoices), choices=add_blank_choice(WirelessAuthCipherChoices),
required=False required=False
) )
@ -115,17 +125,16 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm):
label=_('Pre-shared key') label=_('Pre-shared key')
) )
description = forms.CharField( description = forms.CharField(
label=_('Description'),
max_length=200, max_length=200,
required=False required=False
) )
comments = CommentField( comments = CommentField()
label='Comments'
)
model = WirelessLink model = WirelessLink
fieldsets = ( fieldsets = (
(None, ('ssid', 'status', 'tenant', 'description')), (None, ('ssid', 'status', 'tenant', 'description')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')) (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk'))
) )
nullable_fields = ( nullable_fields = (
'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments', 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'comments',

View File

@ -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.choices import LinkStatusChoices
from dcim.models import Interface from dcim.models import Interface
@ -18,6 +18,7 @@ __all__ = (
class WirelessLANGroupImportForm(NetBoxModelImportForm): class WirelessLANGroupImportForm(NetBoxModelImportForm):
parent = CSVModelChoiceField( parent = CSVModelChoiceField(
label=_('Parent'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
@ -32,33 +33,39 @@ class WirelessLANGroupImportForm(NetBoxModelImportForm):
class WirelessLANImportForm(NetBoxModelImportForm): class WirelessLANImportForm(NetBoxModelImportForm):
group = CSVModelChoiceField( group = CSVModelChoiceField(
label=_('Group'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned group') help_text=_('Assigned group')
) )
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=WirelessLANStatusChoices, choices=WirelessLANStatusChoices,
help_text='Operational status' help_text='Operational status'
) )
vlan = CSVModelChoiceField( vlan = CSVModelChoiceField(
label=_('VLAN'),
queryset=VLAN.objects.all(), queryset=VLAN.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Bridged VLAN') help_text=_('Bridged VLAN')
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
auth_type = CSVChoiceField( auth_type = CSVChoiceField(
label=_('Authentication type'),
choices=WirelessAuthTypeChoices, choices=WirelessAuthTypeChoices,
required=False, required=False,
help_text=_('Authentication type') help_text=_('Authentication type')
) )
auth_cipher = CSVChoiceField( auth_cipher = CSVChoiceField(
label=_('Authentication cipher'),
choices=WirelessAuthCipherChoices, choices=WirelessAuthCipherChoices,
required=False, required=False,
help_text=_('Authentication cipher') help_text=_('Authentication cipher')
@ -74,27 +81,33 @@ class WirelessLANImportForm(NetBoxModelImportForm):
class WirelessLinkImportForm(NetBoxModelImportForm): class WirelessLinkImportForm(NetBoxModelImportForm):
status = CSVChoiceField( status = CSVChoiceField(
label=_('Status'),
choices=LinkStatusChoices, choices=LinkStatusChoices,
help_text=_('Connection status') help_text=_('Connection status')
) )
interface_a = CSVModelChoiceField( interface_a = CSVModelChoiceField(
label=_('Interface A'),
queryset=Interface.objects.all() queryset=Interface.objects.all()
) )
interface_b = CSVModelChoiceField( interface_b = CSVModelChoiceField(
label=_('Interface B'),
queryset=Interface.objects.all() queryset=Interface.objects.all()
) )
tenant = CSVModelChoiceField( tenant = CSVModelChoiceField(
label=_('Tenant'),
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
required=False, required=False,
to_field_name='name', to_field_name='name',
help_text=_('Assigned tenant') help_text=_('Assigned tenant')
) )
auth_type = CSVChoiceField( auth_type = CSVChoiceField(
label=_('Authentication type'),
choices=WirelessAuthTypeChoices, choices=WirelessAuthTypeChoices,
required=False, required=False,
help_text=_('Authentication type') help_text=_('Authentication type')
) )
auth_cipher = CSVChoiceField( auth_cipher = CSVChoiceField(
label=_('Authentication cipher'),
choices=WirelessAuthCipherChoices, choices=WirelessAuthCipherChoices,
required=False, required=False,
help_text=_('Authentication cipher') help_text=_('Authentication cipher')

View File

@ -1,5 +1,5 @@
from django import forms 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 dcim.choices import LinkStatusChoices
from netbox.forms import NetBoxModelFilterSetForm from netbox.forms import NetBoxModelFilterSetForm
@ -30,9 +30,9 @@ class WirelessLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = WirelessLAN model = WirelessLAN
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('ssid', 'group_id', 'status')), (_('Attributes'), ('ssid', 'group_id', 'status')),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
) )
ssid = forms.CharField( ssid = forms.CharField(
required=False, required=False,
@ -45,18 +45,22 @@ class WirelessLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Group') label=_('Group')
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
required=False, required=False,
choices=add_blank_choice(WirelessLANStatusChoices) choices=add_blank_choice(WirelessLANStatusChoices)
) )
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
label=_('Authentication type'),
required=False, required=False,
choices=add_blank_choice(WirelessAuthTypeChoices) choices=add_blank_choice(WirelessAuthTypeChoices)
) )
auth_cipher = forms.ChoiceField( auth_cipher = forms.ChoiceField(
label=_('Authentication cipher'),
required=False, required=False,
choices=add_blank_choice(WirelessAuthCipherChoices) choices=add_blank_choice(WirelessAuthCipherChoices)
) )
auth_psk = forms.CharField( auth_psk = forms.CharField(
label=_('Pre-shared key'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -66,27 +70,31 @@ class WirelessLinkFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
model = WirelessLink model = WirelessLink
fieldsets = ( fieldsets = (
(None, ('q', 'filter_id', 'tag')), (None, ('q', 'filter_id', 'tag')),
('Attributes', ('ssid', 'status',)), (_('Attributes'), ('ssid', 'status',)),
('Tenant', ('tenant_group_id', 'tenant_id')), (_('Tenant'), ('tenant_group_id', 'tenant_id')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
) )
ssid = forms.CharField( ssid = forms.CharField(
required=False, required=False,
label=_('SSID') label=_('SSID')
) )
status = forms.ChoiceField( status = forms.ChoiceField(
label=_('Status'),
required=False, required=False,
choices=add_blank_choice(LinkStatusChoices) choices=add_blank_choice(LinkStatusChoices)
) )
auth_type = forms.ChoiceField( auth_type = forms.ChoiceField(
label=_('Authentication type'),
required=False, required=False,
choices=add_blank_choice(WirelessAuthTypeChoices) choices=add_blank_choice(WirelessAuthTypeChoices)
) )
auth_cipher = forms.ChoiceField( auth_cipher = forms.ChoiceField(
label=_('Authentication cipher'),
required=False, required=False,
choices=add_blank_choice(WirelessAuthCipherChoices) choices=add_blank_choice(WirelessAuthCipherChoices)
) )
auth_psk = forms.CharField( auth_psk = forms.CharField(
label=_('Pre-shared key'),
required=False required=False
) )
tag = TagFilterField(model) tag = TagFilterField(model)

View File

@ -1,5 +1,5 @@
from django.forms import PasswordInput 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 dcim.models import Device, Interface, Location, Site
from ipam.models import VLAN from ipam.models import VLAN
@ -17,13 +17,14 @@ __all__ = (
class WirelessLANGroupForm(NetBoxModelForm): class WirelessLANGroupForm(NetBoxModelForm):
parent = DynamicModelChoiceField( parent = DynamicModelChoiceField(
label=_('Parent'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False required=False
) )
slug = SlugField() slug = SlugField()
fieldsets = ( fieldsets = (
('Wireless LAN Group', ( (_('Wireless LAN Group'), (
'parent', 'name', 'slug', 'description', 'tags', 'parent', 'name', 'slug', 'description', 'tags',
)), )),
) )
@ -37,6 +38,7 @@ class WirelessLANGroupForm(NetBoxModelForm):
class WirelessLANForm(TenancyForm, NetBoxModelForm): class WirelessLANForm(TenancyForm, NetBoxModelForm):
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
label=_('Group'),
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
required=False required=False
) )
@ -49,9 +51,9 @@ class WirelessLANForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Wireless LAN', ('ssid', 'group', 'vlan', 'status', 'description', 'tags')), (_('Wireless LAN'), ('ssid', 'group', 'vlan', 'status', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
) )
class Meta: class Meta:
@ -152,11 +154,11 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm):
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
('Side A', ('site_a', 'location_a', 'device_a', 'interface_a')), (_('Side A'), ('site_a', 'location_a', 'device_a', 'interface_a')),
('Side B', ('site_b', 'location_b', 'device_b', 'interface_b')), (_('Side B'), ('site_b', 'location_b', 'device_b', 'interface_b')),
('Link', ('status', 'ssid', 'description', 'tags')), (_('Link'), ('status', 'ssid', 'description', 'tags')),
('Tenancy', ('tenant_group', 'tenant')), (_('Tenancy'), ('tenant_group', 'tenant')),
('Authentication', ('auth_type', 'auth_cipher', 'auth_psk')), (_('Authentication'), ('auth_type', 'auth_cipher', 'auth_psk')),
) )
class Meta: class Meta: