Closes #5894: Use primary keys when filtering object lists by related objects in the UI

This commit is contained in:
Jeremy Stretch 2021-03-01 17:24:30 -05:00
parent 07e6abdac4
commit 6ed2e7b636
8 changed files with 371 additions and 376 deletions

View File

@ -9,6 +9,7 @@
* [#5370](https://github.com/netbox-community/netbox/issues/5370) - Extend custom field support to organizational models * [#5370](https://github.com/netbox-community/netbox/issues/5370) - Extend custom field support to organizational models
* [#5401](https://github.com/netbox-community/netbox/issues/5401) - Extend custom field support to device component models * [#5401](https://github.com/netbox-community/netbox/issues/5401) - Extend custom field support to device component models
* [#5451](https://github.com/netbox-community/netbox/issues/5451) - Add support for multiple-selection custom fields * [#5451](https://github.com/netbox-community/netbox/issues/5451) - Add support for multiple-selection custom fields
* [#5894](https://github.com/netbox-community/netbox/issues/5894) - Use primary keys when filtering object lists by related objects in the UI
* [#5901](https://github.com/netbox-community/netbox/issues/5901) - Add `created` and `last_updated` fields to device component models * [#5901](https://github.com/netbox-community/netbox/issues/5901) - Add `created` and `last_updated` fields to device component models
### Other Changes ### Other Changes

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext as _
from dcim.models import Region, Site from dcim.models import Region, Site
from extras.forms import ( from extras.forms import (
@ -8,7 +9,7 @@ from extras.models import Tag
from tenancy.forms import TenancyFilterForm, TenancyForm from tenancy.forms import TenancyFilterForm, TenancyForm
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.forms import ( from utilities.forms import (
add_blank_choice, BootstrapMixin, CommentField, CSVChoiceField, CSVModelChoiceField, CSVModelForm, DatePicker, add_blank_choice, BootstrapMixin, CommentField, CSVChoiceField, CSVModelChoiceField, DatePicker,
DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SmallTextarea, SlugField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SmallTextarea, SlugField,
StaticSelect2, StaticSelect2Multiple, TagFilterField, StaticSelect2, StaticSelect2Multiple, TagFilterField,
) )
@ -105,24 +106,24 @@ class ProviderFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = Provider model = Provider
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
asn = forms.IntegerField( asn = forms.IntegerField(
required=False, required=False,
label='ASN' label=_('ASN')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -265,44 +266,44 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Circuit model = Circuit
field_order = [ field_order = [
'q', 'type', 'provider', 'status', 'region', 'site', 'tenant_group', 'tenant', 'commit_rate', 'q', 'type_id', 'provider_id', 'status', 'region_id', 'site_id', 'tenant_group_id', 'tenant_id', 'commit_rate',
] ]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
type = DynamicModelMultipleChoiceField( type_id = DynamicModelMultipleChoiceField(
queryset=CircuitType.objects.all(), queryset=CircuitType.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Type')
) )
provider = DynamicModelMultipleChoiceField( provider_id = DynamicModelMultipleChoiceField(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Provider')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=CircuitStatusChoices, choices=CircuitStatusChoices,
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
commit_rate = forms.IntegerField( commit_rate = forms.IntegerField(
required=False, required=False,
min_value=0, min_value=0,
label='Commit rate (Kbps)' label=_('Commit rate (Kbps)')
) )
tag = TagFilterField(model) tag = TagFilterField(model)

View File

@ -6,6 +6,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 netaddr import EUI from netaddr import EUI
from netaddr.core import AddrFormatError from netaddr.core import AddrFormatError
from timezone_field import TimeZoneFormField from timezone_field import TimeZoneFormField
@ -19,7 +20,7 @@ from extras.models import Tag
from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN from ipam.constants import BGP_ASN_MAX, BGP_ASN_MIN
from ipam.models import IPAddress, VLAN from ipam.models import IPAddress, VLAN
from tenancy.forms import TenancyFilterForm, TenancyForm from tenancy.forms import TenancyFilterForm, TenancyForm
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant
from utilities.forms import ( from utilities.forms import (
APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, APISelect, APISelectMultiple, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
ColorSelect, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, DynamicModelChoiceField, ColorSelect, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, DynamicModelChoiceField,
@ -59,32 +60,32 @@ def get_device_by_name_or_pk(name):
class DeviceComponentFilterForm(BootstrapMixin, CustomFieldFilterForm): class DeviceComponentFilterForm(BootstrapMixin, CustomFieldFilterForm):
field_order = [ field_order = [
'q', 'region', 'site' 'q', 'region_id', 'site_id'
] ]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
device_id = DynamicModelMultipleChoiceField( device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
label='Device',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Device')
) )
@ -203,7 +204,7 @@ class RegionFilterForm(BootstrapMixin, forms.Form):
model = Site model = Site
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
@ -337,20 +338,20 @@ class SiteBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Site model = Site
field_order = ['q', 'status', 'region', 'tenant_group', 'tenant'] field_order = ['q', 'status', 'region_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=SiteStatusChoices, choices=SiteStatusChoices,
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -411,27 +412,27 @@ class RackGroupCSVForm(CustomFieldModelCSVForm):
class RackGroupFilterForm(BootstrapMixin, forms.Form): class RackGroupFilterForm(BootstrapMixin, forms.Form):
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
parent = DynamicModelMultipleChoiceField( parent = DynamicModelMultipleChoiceField(
queryset=RackGroup.objects.all(), queryset=RackGroup.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region', 'region_id': '$region_id',
'site': '$site', 'site_id': '$site_id',
} },
label=_('Parent')
) )
@ -666,32 +667,32 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Rack model = Rack
field_order = ['q', 'region', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant'] field_order = ['q', 'region_id', 'site_id', 'group_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
group_id = DynamicModelMultipleChoiceField( group_id = DynamicModelMultipleChoiceField(
queryset=RackGroup.objects.all(), queryset=RackGroup.objects.all(),
required=False, required=False,
label='Rack group',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Rack group')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=RackStatusChoices, choices=RackStatusChoices,
@ -708,11 +709,11 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=RackRole.objects.all(), queryset=RackRole.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Role')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -722,15 +723,15 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
# #
class RackElevationFilterForm(RackFilterForm): class RackElevationFilterForm(RackFilterForm):
field_order = ['q', 'region', 'site', 'group_id', 'id', 'status', 'role', 'tenant_group', 'tenant'] field_order = ['q', 'region_id', 'site_id', 'group_id', 'id', 'status', 'role_id', 'tenant_group_id', 'tenant_id']
id = DynamicModelMultipleChoiceField( id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
label='Rack', label=_('Rack'),
required=False, required=False,
display_field='display_name', display_field='display_name',
query_params={ query_params={
'site': '$site', 'site_id': '$site_id',
'group_id': '$group_id', 'group_id_id': '$group_id_id',
} }
) )
@ -872,23 +873,23 @@ class RackReservationBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomField
class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm): class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm):
model = RackReservation model = RackReservation
field_order = ['q', 'region', 'site', 'group_id', 'user_id', 'tenant_group', 'tenant'] field_order = ['q', 'region_id', 'site_id', 'group_id', 'user_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Region')
) )
group_id = DynamicModelMultipleChoiceField( group_id = DynamicModelMultipleChoiceField(
queryset=RackGroup.objects.prefetch_related('site'), queryset=RackGroup.objects.prefetch_related('site'),
@ -1011,12 +1012,12 @@ class DeviceTypeFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = DeviceType model = DeviceType
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
manufacturer = DynamicModelMultipleChoiceField( manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Manufacturer')
) )
subdevice_role = forms.MultipleChoiceField( subdevice_role = forms.MultipleChoiceField(
choices=add_blank_choice(SubdeviceRoleChoices), choices=add_blank_choice(SubdeviceRoleChoices),
@ -2133,69 +2134,66 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldFilterForm): class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldFilterForm):
model = Device model = Device
field_order = [ field_order = [
'q', 'region', 'site', 'rack_group_id', 'rack_id', 'status', 'role', 'tenant_group', 'tenant', 'q', 'region_id', 'site_id', 'rack_group_id', 'rack_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id',
'manufacturer_id', 'device_type_id', 'mac_address', 'has_primary_ip', 'manufacturer_id', 'device_type_id', 'mac_address', 'has_primary_ip',
] ]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug',
required=False required=False
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} }
) )
rack_group_id = DynamicModelMultipleChoiceField( rack_group_id = DynamicModelMultipleChoiceField(
queryset=RackGroup.objects.all(), queryset=RackGroup.objects.all(),
required=False, required=False,
label='Rack group', label=_('Rack group'),
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} }
) )
rack_id = DynamicModelMultipleChoiceField( rack_id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
label='Rack',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site', 'site_id': '$site_id',
'group_id': '$rack_group_id', 'group_id': '$rack_group_id',
} },
label=_('Rack')
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
to_field_name='slug',
required=False
)
manufacturer = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),
to_field_name='slug',
required=False, required=False,
label='Manufacturer' label=_('Role')
)
manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(),
required=False,
label=_('Manufacturer')
) )
device_type_id = DynamicModelMultipleChoiceField( device_type_id = DynamicModelMultipleChoiceField(
queryset=DeviceType.objects.all(), queryset=DeviceType.objects.all(),
required=False, required=False,
label='Model',
display_field='model', display_field='model',
query_params={ query_params={
'manufacturer': '$manufacturer' 'manufacturer_id': '$manufacturer_id'
} },
label=_('Model')
) )
platform = DynamicModelMultipleChoiceField( platform_id = DynamicModelMultipleChoiceField(
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Platform')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=DeviceStatusChoices, choices=DeviceStatusChoices,
@ -3540,10 +3538,10 @@ class InventoryItemBulkEditForm(
class InventoryItemFilterForm(DeviceComponentFilterForm): class InventoryItemFilterForm(DeviceComponentFilterForm):
model = InventoryItem model = InventoryItem
manufacturer = DynamicModelMultipleChoiceField( manufacturer_id = DynamicModelMultipleChoiceField(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Manufacturer')
) )
serial = forms.CharField( serial = forms.CharField(
required=False required=False
@ -3988,25 +3986,25 @@ class CableFilterForm(BootstrapMixin, forms.Form):
model = Cable model = Cable
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
tenant = DynamicModelMultipleChoiceField( tenant_id = DynamicModelMultipleChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Tenant')
) )
rack_id = DynamicModelMultipleChoiceField( rack_id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
@ -4014,7 +4012,7 @@ class CableFilterForm(BootstrapMixin, forms.Form):
label='Rack', label='Rack',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} }
) )
type = forms.MultipleChoiceField( type = forms.MultipleChoiceField(
@ -4035,12 +4033,12 @@ class CableFilterForm(BootstrapMixin, forms.Form):
device_id = DynamicModelMultipleChoiceField( device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
label='Device',
query_params={ query_params={
'site': '$site', 'site_id': '$site_id',
'tenant': '$tenant', 'tenant_id': '$tenant_id',
'rack_id': '$rack_id', 'rack_id': '$rack_id',
} },
label=_('Device')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -4050,74 +4048,74 @@ class CableFilterForm(BootstrapMixin, forms.Form):
# #
class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form): class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
device_id = DynamicModelMultipleChoiceField( device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
label='Device',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Device')
) )
class PowerConnectionFilterForm(BootstrapMixin, forms.Form): class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
device_id = DynamicModelMultipleChoiceField( device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
label='Device',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Device')
) )
class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form): class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
device_id = DynamicModelMultipleChoiceField( device_id = DynamicModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
required=False, required=False,
label='Device',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Device')
) )
@ -4344,39 +4342,25 @@ class VirtualChassisCSVForm(CustomFieldModelCSVForm):
fields = VirtualChassis.csv_headers fields = VirtualChassis.csv_headers
class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm): class VirtualChassisFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VirtualChassis model = VirtualChassis
field_order = ['q', 'region_id', 'site_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
) label=_('Site')
tenant_group = DynamicModelMultipleChoiceField(
queryset=TenantGroup.objects.all(),
to_field_name='slug',
required=False,
null_option='None'
)
tenant = DynamicModelMultipleChoiceField(
queryset=Tenant.objects.all(),
to_field_name='slug',
required=False,
null_option='None',
query_params={
'group': '$tenant_group'
}
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -4482,29 +4466,29 @@ class PowerPanelFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = PowerPanel model = PowerPanel
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
rack_group_id = DynamicModelMultipleChoiceField( rack_group_id = DynamicModelMultipleChoiceField(
queryset=RackGroup.objects.all(), queryset=RackGroup.objects.all(),
required=False, required=False,
label='Rack group (ID)',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Rack group')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -4701,38 +4685,38 @@ class PowerFeedFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = PowerFeed model = PowerFeed
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
power_panel_id = DynamicModelMultipleChoiceField( power_panel_id = DynamicModelMultipleChoiceField(
queryset=PowerPanel.objects.all(), queryset=PowerPanel.objects.all(),
required=False, required=False,
label='Power panel',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Power panel')
) )
rack_id = DynamicModelMultipleChoiceField( rack_id = DynamicModelMultipleChoiceField(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
required=False, required=False,
label='Rack',
null_option='None', null_option='None',
query_params={ query_params={
'site': '$site' 'site_id': '$site_id'
} },
label=_('Rack')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=PowerFeedStatusChoices, choices=PowerFeedStatusChoices,

View File

@ -2,6 +2,7 @@ from django import forms
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils.safestring import mark_safe from django.utils.safestring import mark_safe
from django.utils.translation import gettext as _
from dcim.models import DeviceRole, Platform, Region, Site from dcim.models import DeviceRole, Platform, Region, Site
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
@ -177,7 +178,7 @@ class TagFilterForm(BootstrapMixin, forms.Form):
model = Tag model = Tag
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
@ -278,54 +279,59 @@ class ConfigContextBulkEditForm(BootstrapMixin, BulkEditForm):
class ConfigContextFilterForm(BootstrapMixin, forms.Form): class ConfigContextFilterForm(BootstrapMixin, forms.Form):
field_order = [
'q', 'region_id', 'site_id', 'role_id', 'platform_id', 'cluster_group_id', 'cluster_id', 'tenant_group_id',
'tenant_id',
]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Regions')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Sites')
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=DeviceRole.objects.all(), queryset=DeviceRole.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Roles')
) )
platform = DynamicModelMultipleChoiceField( platform_id = DynamicModelMultipleChoiceField(
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Platforms')
) )
cluster_group = DynamicModelMultipleChoiceField( cluster_group_id = DynamicModelMultipleChoiceField(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Cluster groups')
) )
cluster_id = DynamicModelMultipleChoiceField( cluster_id = DynamicModelMultipleChoiceField(
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
label='Cluster' label=_('Clusters')
) )
tenant_group = DynamicModelMultipleChoiceField( tenant_group_id = DynamicModelMultipleChoiceField(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Tenant groups')
) )
tenant = DynamicModelMultipleChoiceField( tenant_id = DynamicModelMultipleChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Tenant')
) )
tag = DynamicModelMultipleChoiceField( tag = DynamicModelMultipleChoiceField(
queryset=Tag.objects.all(), queryset=Tag.objects.all(),
to_field_name='slug', to_field_name='slug',
required=False required=False,
label=_('Tags')
) )
@ -336,7 +342,7 @@ class ConfigContextFilterForm(BootstrapMixin, forms.Form):
class LocalConfigContextFilterForm(forms.Form): class LocalConfigContextFilterForm(forms.Form):
local_context_data = forms.NullBooleanField( local_context_data = forms.NullBooleanField(
required=False, required=False,
label='Has local config context data', label=_('Has local config context data'),
widget=StaticSelect2( widget=StaticSelect2(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -364,16 +370,16 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
model = ObjectChange model = ObjectChange
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
time_after = forms.DateTimeField( time_after = forms.DateTimeField(
label='After',
required=False, required=False,
label=_('After'),
widget=DateTimePicker() widget=DateTimePicker()
) )
time_before = forms.DateTimeField( time_before = forms.DateTimeField(
label='Before',
required=False, required=False,
label=_('Before'),
widget=DateTimePicker() widget=DateTimePicker()
) )
action = forms.ChoiceField( action = forms.ChoiceField(
@ -385,7 +391,7 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
queryset=User.objects.all(), queryset=User.objects.all(),
required=False, required=False,
display_field='username', display_field='username',
label='User', label=_('User'),
widget=APISelectMultiple( widget=APISelectMultiple(
api_url='/api/users/users/', api_url='/api/users/users/',
) )
@ -394,7 +400,7 @@ class ObjectChangeFilterForm(BootstrapMixin, forms.Form):
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
required=False, required=False,
display_field='display_name', display_field='display_name',
label='Object Type', label=_('Object Type'),
widget=APISelectMultiple( widget=APISelectMultiple(
api_url='/api/extras/content-types/', api_url='/api/extras/content-types/',
) )

View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from django.utils.translation import gettext as _
from dcim.models import Device, Interface, Rack, Region, Site from dcim.models import Device, Interface, Rack, Region, Site
from extras.forms import ( from extras.forms import (
@ -103,20 +104,20 @@ class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm
class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VRF model = VRF
field_order = ['q', 'import_target', 'export_target', 'tenant_group', 'tenant'] field_order = ['q', 'import_target_id', 'export_target_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
import_target = DynamicModelMultipleChoiceField( import_target_id = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
to_field_name='name', required=False,
required=False label=_('Import targets')
) )
export_target = DynamicModelMultipleChoiceField( export_target_id = DynamicModelMultipleChoiceField(
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
to_field_name='name', required=False,
required=False label=_('Export targets')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -173,20 +174,20 @@ class RouteTargetBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulk
class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class RouteTargetFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = RouteTarget model = RouteTarget
field_order = ['q', 'name', 'tenant_group', 'tenant', 'importing_vrfs', 'exporting_vrfs'] field_order = ['q', 'name', 'tenant_group_id', 'tenant_id', 'importing_vrfs', 'exporting_vrfs']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
importing_vrf_id = DynamicModelMultipleChoiceField( importing_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Imported by VRF' label=_('Imported by VRF')
) )
exporting_vrf_id = DynamicModelMultipleChoiceField( exporting_vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Exported by VRF' label=_('Exported by VRF')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -219,7 +220,7 @@ class RIRCSVForm(CustomFieldModelCSVForm):
class RIRFilterForm(BootstrapMixin, forms.Form): class RIRFilterForm(BootstrapMixin, forms.Form):
is_private = forms.NullBooleanField( is_private = forms.NullBooleanField(
required=False, required=False,
label='Private', label=_('Private'),
widget=StaticSelect2( widget=StaticSelect2(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -309,21 +310,21 @@ class AggregateBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEd
class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class AggregateFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Aggregate model = Aggregate
field_order = ['q', 'family', 'rir', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
family = forms.ChoiceField( family = forms.ChoiceField(
required=False, required=False,
choices=add_blank_choice(IPAddressFamilyChoices), choices=add_blank_choice(IPAddressFamilyChoices),
label='Address family', label=_('Address family'),
widget=StaticSelect2() widget=StaticSelect2()
) )
rir = DynamicModelMultipleChoiceField( rir_id = DynamicModelMultipleChoiceField(
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
to_field_name='slug',
required=False, required=False,
label='RIR' label=_('RIR')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -494,14 +495,13 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
) )
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False
to_field_name='slug'
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region'
} }
) )
vrf = DynamicModelChoiceField( vrf = DynamicModelChoiceField(
@ -547,15 +547,15 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Prefix model = Prefix
field_order = [ field_order = [
'q', 'within_include', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'region', 'site', 'q', 'within_include', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'region_id', 'site_id',
'role', 'tenant_group', 'tenant', 'is_pool', 'expand', 'role_id', 'tenant_group_id', 'tenant_id', 'is_pool',
] ]
mask_length__lte = forms.IntegerField( mask_length__lte = forms.IntegerField(
widget=forms.HiddenInput() widget=forms.HiddenInput()
) )
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
within_include = forms.CharField( within_include = forms.CharField(
required=False, required=False,
@ -564,59 +564,59 @@ class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
'placeholder': 'Prefix', 'placeholder': 'Prefix',
} }
), ),
label='Search within' label=_('Search within')
) )
family = forms.ChoiceField( family = forms.ChoiceField(
required=False, required=False,
choices=add_blank_choice(IPAddressFamilyChoices), choices=add_blank_choice(IPAddressFamilyChoices),
label='Address family', label=_('Address family'),
widget=StaticSelect2() widget=StaticSelect2()
) )
mask_length = forms.ChoiceField( mask_length = forms.ChoiceField(
required=False, required=False,
choices=PREFIX_MASK_LENGTH_CHOICES, choices=PREFIX_MASK_LENGTH_CHOICES,
label='Mask length', label=_('Mask length'),
widget=StaticSelect2() widget=StaticSelect2()
) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Assigned VRF', label=_('Assigned VRF'),
null_option='Global' null_option='Global'
) )
present_in_vrf_id = DynamicModelChoiceField( present_in_vrf_id = DynamicModelChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Present in VRF' label=_('Present in VRF')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=PrefixStatusChoices, choices=PrefixStatusChoices,
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=Role.objects.all(), queryset=Role.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Role')
) )
is_pool = forms.NullBooleanField( is_pool = forms.NullBooleanField(
required=False, required=False,
label='Is a pool', label=_('Is a pool'),
widget=StaticSelect2( widget=StaticSelect2(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -1019,11 +1019,11 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterFo
model = IPAddress model = IPAddress
field_order = [ field_order = [
'q', 'parent', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'role', 'q', 'parent', 'family', 'mask_length', 'vrf_id', 'present_in_vrf_id', 'status', 'role',
'assigned_to_interface', 'tenant_group', 'tenant', 'assigned_to_interface', 'tenant_group_id', 'tenant_id',
] ]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
parent = forms.CharField( parent = forms.CharField(
required=False, required=False,
@ -1037,25 +1037,25 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterFo
family = forms.ChoiceField( family = forms.ChoiceField(
required=False, required=False,
choices=add_blank_choice(IPAddressFamilyChoices), choices=add_blank_choice(IPAddressFamilyChoices),
label='Address family', label=_('Address family'),
widget=StaticSelect2() widget=StaticSelect2()
) )
mask_length = forms.ChoiceField( mask_length = forms.ChoiceField(
required=False, required=False,
choices=IPADDRESS_MASK_LENGTH_CHOICES, choices=IPADDRESS_MASK_LENGTH_CHOICES,
label='Mask length', label=_('Mask length'),
widget=StaticSelect2() widget=StaticSelect2()
) )
vrf_id = DynamicModelMultipleChoiceField( vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Assigned VRF', label=_('Assigned VRF'),
null_option='Global' null_option='Global'
) )
present_in_vrf_id = DynamicModelChoiceField( present_in_vrf_id = DynamicModelChoiceField(
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
required=False, required=False,
label='Present in VRF' label=_('Present in VRF')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=IPAddressStatusChoices, choices=IPAddressStatusChoices,
@ -1069,7 +1069,7 @@ class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterFo
) )
assigned_to_interface = forms.NullBooleanField( assigned_to_interface = forms.NullBooleanField(
required=False, required=False,
label='Assigned to an interface', label=_('Assigned to an interface'),
widget=StaticSelect2( widget=StaticSelect2(
choices=BOOLEAN_WITH_BLANK_CHOICES choices=BOOLEAN_WITH_BLANK_CHOICES
) )
@ -1120,19 +1120,19 @@ class VLANGroupCSVForm(CustomFieldModelCSVForm):
class VLANGroupFilterForm(BootstrapMixin, forms.Form): class VLANGroupFilterForm(BootstrapMixin, forms.Form):
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
@ -1250,14 +1250,13 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
) )
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False
to_field_name='slug'
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region'
} }
) )
group = DynamicModelChoiceField( group = DynamicModelChoiceField(
@ -1293,44 +1292,44 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VLAN model = VLAN
field_order = ['q', 'region', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant'] field_order = ['q', 'region_id', 'site_id', 'group_id', 'status', 'role_id', 'tenant_group_id', 'tenant_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region': '$region'
} },
label=_('Site')
) )
group_id = DynamicModelMultipleChoiceField( group_id = DynamicModelMultipleChoiceField(
queryset=VLANGroup.objects.all(), queryset=VLANGroup.objects.all(),
required=False, required=False,
label='VLAN group',
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region': '$region'
} },
label=_('VLAN group')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=VLANStatusChoices, choices=VLANStatusChoices,
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=Role.objects.all(), queryset=Role.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Role')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -1386,7 +1385,7 @@ class ServiceFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = Service model = Service
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
protocol = forms.ChoiceField( protocol = forms.ChoiceField(
choices=add_blank_choice(ServiceProtocolChoices), choices=add_blank_choice(ServiceProtocolChoices),

View File

@ -1,7 +1,7 @@
from Crypto.Cipher import PKCS1_OAEP from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA from Crypto.PublicKey import RSA
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.utils.translation import gettext as _
from dcim.models import Device from dcim.models import Device
from extras.forms import ( from extras.forms import (
@ -9,7 +9,7 @@ from extras.forms import (
) )
from extras.models import Tag from extras.models import Tag
from utilities.forms import ( from utilities.forms import (
BootstrapMixin, CSVModelChoiceField, CSVModelForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField, BootstrapMixin, CSVModelChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
SlugField, TagFilterField, SlugField, TagFilterField,
) )
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
@ -221,12 +221,12 @@ class SecretFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = Secret model = Secret
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=SecretRole.objects.all(), queryset=SecretRole.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Role')
) )
tag = TagFilterField(model) tag = TagFilterField(model)

View File

@ -1,12 +1,13 @@
from django import forms from django import forms
from django.utils.translation import gettext as _
from extras.forms import ( from extras.forms import (
AddRemoveTagsForm, CustomFieldModelForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelCSVForm, AddRemoveTagsForm, CustomFieldModelForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelCSVForm,
) )
from extras.models import Tag from extras.models import Tag
from utilities.forms import ( from utilities.forms import (
BootstrapMixin, CommentField, CSVModelChoiceField, CSVModelForm, DynamicModelChoiceField, BootstrapMixin, CommentField, CSVModelChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
DynamicModelMultipleChoiceField, SlugField, TagFilterField, SlugField, TagFilterField,
) )
from .models import Tenant, TenantGroup from .models import Tenant, TenantGroup
@ -103,13 +104,13 @@ class TenantFilterForm(BootstrapMixin, CustomFieldFilterForm):
model = Tenant model = Tenant
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
group = DynamicModelMultipleChoiceField( group_id = DynamicModelMultipleChoiceField(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Group')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -137,18 +138,18 @@ class TenancyForm(forms.Form):
class TenancyFilterForm(forms.Form): class TenancyFilterForm(forms.Form):
tenant_group = DynamicModelMultipleChoiceField( tenant_group_id = DynamicModelMultipleChoiceField(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Tenant group')
) )
tenant = DynamicModelMultipleChoiceField( tenant_id = DynamicModelMultipleChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'group': '$tenant_group' 'group_id': '$tenant_group_id'
} },
label=_('Tenant')
) )

View File

@ -1,6 +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 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
@ -160,13 +161,12 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
required=False, required=False,
to_field_name='slug'
) )
site = DynamicModelChoiceField( site = DynamicModelChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
required=False, required=False,
query_params={ query_params={
'region': '$region' 'region_id': '$region'
} }
) )
comments = CommentField( comments = CommentField(
@ -183,33 +183,36 @@ class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class ClusterFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Cluster model = Cluster
field_order = [ field_order = [
'q', 'type', 'region', 'site', 'group', 'tenant_group', 'tenant' 'q', 'type_id', 'region_id', 'site_id', 'group_id', 'tenant_group_id', 'tenant_id',
] ]
q = forms.CharField(required=False, label='Search') q = forms.CharField(
type = DynamicModelMultipleChoiceField( required=False,
label=_('Search')
)
type_id = DynamicModelMultipleChoiceField(
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Type')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Site')
) )
group = DynamicModelMultipleChoiceField( group_id = DynamicModelMultipleChoiceField(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Group')
) )
tag = TagFilterField(model) tag = TagFilterField(model)
@ -478,63 +481,63 @@ class VirtualMachineBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldB
class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VirtualMachine model = VirtualMachine
field_order = [ field_order = [
'q', 'cluster_group', 'cluster_type', 'cluster_id', 'status', 'role', 'region', 'site', 'tenant_group', 'q', 'cluster_group_id', 'cluster_type_id', 'cluster_id', 'status', 'role_id', 'region_id', 'site_id',
'tenant', 'platform', 'mac_address', 'tenant_group_id', 'tenant_id', 'platform_id', 'mac_address',
] ]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label=_('Search')
) )
cluster_group = DynamicModelMultipleChoiceField( cluster_group_id = DynamicModelMultipleChoiceField(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Cluster group')
) )
cluster_type = DynamicModelMultipleChoiceField( cluster_type_id = DynamicModelMultipleChoiceField(
queryset=ClusterType.objects.all(), queryset=ClusterType.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Cluster type')
) )
cluster_id = DynamicModelMultipleChoiceField( cluster_id = DynamicModelMultipleChoiceField(
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
label='Cluster' label=_('Cluster')
) )
region = DynamicModelMultipleChoiceField( region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),
to_field_name='slug', required=False,
required=False label=_('Region')
) )
site = DynamicModelMultipleChoiceField( site_id = DynamicModelMultipleChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'region': '$region' 'region_id': '$region_id'
} },
label=_('Cluster')
) )
role = DynamicModelMultipleChoiceField( role_id = DynamicModelMultipleChoiceField(
queryset=DeviceRole.objects.filter(vm_role=True), queryset=DeviceRole.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None', null_option='None',
query_params={ query_params={
'vm_role': "True" 'vm_role': "True"
} },
label=_('Role')
) )
status = forms.MultipleChoiceField( status = forms.MultipleChoiceField(
choices=VirtualMachineStatusChoices, choices=VirtualMachineStatusChoices,
required=False, required=False,
widget=StaticSelect2Multiple() widget=StaticSelect2Multiple()
) )
platform = DynamicModelMultipleChoiceField( platform_id = DynamicModelMultipleChoiceField(
queryset=Platform.objects.all(), queryset=Platform.objects.all(),
to_field_name='slug',
required=False, required=False,
null_option='None' null_option='None',
label=_('Platform')
) )
mac_address = forms.CharField( mac_address = forms.CharField(
required=False, required=False,
@ -781,15 +784,15 @@ class VMInterfaceFilterForm(forms.Form):
cluster_id = DynamicModelMultipleChoiceField( cluster_id = DynamicModelMultipleChoiceField(
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
required=False, required=False,
label='Cluster' label=_('Cluster')
) )
virtual_machine_id = DynamicModelMultipleChoiceField( virtual_machine_id = DynamicModelMultipleChoiceField(
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
required=False, required=False,
label='Virtual machine',
query_params={ query_params={
'cluster_id': '$cluster_id' 'cluster_id': '$cluster_id'
} },
label=_('Virtual machine')
) )
enabled = forms.NullBooleanField( enabled = forms.NullBooleanField(
required=False, required=False,