netbox/netbox/utilities/forms/forms.py

142 lines
3.6 KiB
Python

import re
from django import forms
from django.utils.translation import gettext as _
from .mixins import BootstrapMixin
__all__ = (
'BulkEditForm',
'BulkRenameForm',
'ConfirmationForm',
'CSVModelForm',
'FilterForm',
'TableConfigForm',
)
class ConfirmationForm(BootstrapMixin, forms.Form):
"""
A generic confirmation form. The form is not valid unless the `confirm` field is checked.
"""
return_url = forms.CharField(
required=False,
widget=forms.HiddenInput()
)
confirm = forms.BooleanField(
required=True,
widget=forms.HiddenInput(),
initial=True
)
class BulkEditForm(BootstrapMixin, forms.Form):
"""
Provides bulk edit support for objects.
"""
nullable_fields = ()
class BulkRenameForm(BootstrapMixin, forms.Form):
"""
An extendable form to be used for renaming objects in bulk.
"""
find = forms.CharField(
strip=False
)
replace = forms.CharField(
strip=False,
required=False
)
use_regex = forms.BooleanField(
required=False,
initial=True,
label=_('Use regular expressions')
)
def clean(self):
super().clean()
# Validate regular expression in "find" field
if self.cleaned_data['use_regex']:
try:
re.compile(self.cleaned_data['find'])
except re.error:
raise forms.ValidationError({
'find': "Invalid regular expression"
})
class CSVModelForm(forms.ModelForm):
"""
ModelForm used for the import of objects in CSV format.
"""
id = forms.IntegerField(
label=_('ID'),
required=False,
help_text=_('Numeric ID of an existing object to update (if not creating a new object)')
)
def __init__(self, *args, headers=None, **kwargs):
self.headers = headers or {}
super().__init__(*args, **kwargs)
# Modify the model form to accommodate any customized to_field_name properties
for field, to_field in self.headers.items():
if to_field is not None:
self.fields[field].to_field_name = to_field
def clean(self):
# Flag any invalid CSV headers
for header in self.headers:
if header not in self.fields:
raise forms.ValidationError(
_("Unrecognized header: {name}").format(name=header)
)
return super().clean()
class FilterForm(BootstrapMixin, forms.Form):
"""
Base Form class for FilterSet forms.
"""
q = forms.CharField(
required=False,
label=_('Search')
)
class TableConfigForm(BootstrapMixin, forms.Form):
"""
Form for configuring user's table preferences.
"""
available_columns = forms.MultipleChoiceField(
choices=[],
required=False,
widget=forms.SelectMultiple(
attrs={'size': 10, 'class': 'form-select'}
),
label=_('Available Columns')
)
columns = forms.MultipleChoiceField(
choices=[],
required=False,
widget=forms.SelectMultiple(
attrs={'size': 10, 'class': 'form-select'}
),
label=_('Selected Columns')
)
def __init__(self, table, *args, **kwargs):
self.table = table
super().__init__(*args, **kwargs)
# Initialize columns field based on table attributes
self.fields['available_columns'].choices = table.available_columns
self.fields['columns'].choices = table.selected_columns
@property
def table_name(self):
return self.table.__class__.__name__