Cleanup from #2931

This commit is contained in:
Jeremy Stretch 2019-05-09 14:32:49 -04:00
parent 7895ccfae1
commit fbde6282b2
13 changed files with 142 additions and 73 deletions

View File

@ -2,6 +2,7 @@
## Enhancements ## Enhancements
* [#2813](https://github.com/digitalocean/netbox/issues/2813) - Add tenant group filters
* [#3150](https://github.com/digitalocean/netbox/issues/3150) - Fix formatting of cable length during cable trace * [#3150](https://github.com/digitalocean/netbox/issues/3150) - Fix formatting of cable length during cable trace
* [#3085](https://github.com/digitalocean/netbox/issues/3085) - Catch all exceptions during export template rendering * [#3085](https://github.com/digitalocean/netbox/issues/3085) - Catch all exceptions during export template rendering

View File

@ -3,13 +3,13 @@ from django.db.models import Q
from dcim.models import Site from dcim.models import Site
from extras.filters import CustomFieldFilterSet from extras.filters import CustomFieldFilterSet
from tenancy.filterset import TenancyFilterSet from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter
from .constants import CIRCUIT_STATUS_CHOICES from .constants import CIRCUIT_STATUS_CHOICES
from .models import Provider, Circuit, CircuitTermination, CircuitType from .models import Provider, Circuit, CircuitTermination, CircuitType
class ProviderFilter(CustomFieldFilterSet, django_filters.FilterSet): class ProviderFilter(CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -54,7 +54,7 @@ class CircuitTypeFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug'] fields = ['name', 'slug']
class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet, django_filters.FilterSet): class CircuitFilter(CustomFieldFilterSet, TenancyFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'

View File

@ -268,8 +268,7 @@ class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEdit
class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class CircuitFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Circuit model = Circuit
# Order the form fields, fields not listed are appended field_order = ['q', 'type', 'provider', 'status', 'site', 'tenant_group', 'tenant', 'commit_rate']
field_order = ['q', 'type', 'provider', 'status']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'

View File

@ -1,13 +1,13 @@
import django_filters import django_filters
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q from django.db.models import Q
from netaddr import EUI from netaddr import EUI
from netaddr.core import AddrFormatError from netaddr.core import AddrFormatError
from extras.filters import CustomFieldFilterSet from extras.filters import CustomFieldFilterSet
from tenancy.filterset import TenancyFilterSet from tenancy.filtersets import TenancyFilterSet
from tenancy.models import Tenant
from utilities.constants import COLOR_CHOICES from utilities.constants import COLOR_CHOICES
from utilities.filters import ( from utilities.filters import (
NameSlugSearchFilterSet, NullableCharFieldFilter, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter NameSlugSearchFilterSet, NullableCharFieldFilter, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
@ -39,7 +39,7 @@ class RegionFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug'] fields = ['name', 'slug']
class SiteFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class SiteFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -114,7 +114,7 @@ class RackRoleFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug', 'color'] fields = ['name', 'slug', 'color']
class RackFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class RackFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -180,7 +180,7 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSe
) )
class RackReservationFilter(TenancyFilterSet, django_filters.FilterSet): class RackReservationFilter(TenancyFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -875,7 +875,7 @@ class InventoryItemFilter(DeviceComponentFilterSet):
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class VirtualChassisFilter(TenancyFilterSet, django_filters.FilterSet): class VirtualChassisFilter(django_filters.FilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -891,6 +891,17 @@ class VirtualChassisFilter(TenancyFilterSet, django_filters.FilterSet):
to_field_name='slug', to_field_name='slug',
label='Site name (slug)', label='Site name (slug)',
) )
tenant_id = django_filters.ModelMultipleChoiceFilter(
field_name='master__tenant',
queryset=Tenant.objects.all(),
label='Tenant (ID)',
)
tenant = django_filters.ModelMultipleChoiceFilter(
field_name='master__tenant__slug',
queryset=Tenant.objects.all(),
to_field_name='slug',
label='Tenant (slug)',
)
tag = TagFilter() tag = TagFilter()
class Meta: class Meta:

View File

@ -14,7 +14,7 @@ from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEdit
from ipam.models import IPAddress, VLAN, VLANGroup from ipam.models import IPAddress, VLAN, VLANGroup
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from tenancy.formset import TenancyFilterForm from tenancy.formset import TenancyFilterForm
from tenancy.models import Tenant from tenancy.models import Tenant, TenantGroup
from utilities.forms import ( from utilities.forms import (
APISelect, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, APISelect, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm,
BulkEditNullBooleanSelect, ChainedFieldsMixin, ChainedModelChoiceField, ColorSelect, CommentField, BulkEditNullBooleanSelect, ChainedFieldsMixin, ChainedModelChoiceField, ColorSelect, CommentField,
@ -259,8 +259,7 @@ class SiteBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class SiteFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Site model = Site
# Order the form fields, fields not listed are appended field_order = ['q', 'status', 'region', 'tenant_group', 'tenant']
field_order = ['q', 'status', 'region']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -591,8 +590,7 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Rack model = Rack
# Order the form fields, fields not listed are appended field_order = ['q', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant']
field_order = ['q', 'site', 'group_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -674,32 +672,6 @@ class RackReservationForm(BootstrapMixin, TenancyForm, forms.ModelForm):
return unit_choices return unit_choices
class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm, forms.Form):
# Order the form fields, fields not listed are appended
field_order = ['q', 'site', 'group_id']
q = forms.CharField(
required=False,
label='Search'
)
site = FilterChoiceField(
queryset=Site.objects.all(),
to_field_name='slug',
widget=APISelectMultiple(
api_url="/api/dcim/sites/",
value_field="slug",
)
)
group_id = FilterChoiceField(
queryset=RackGroup.objects.select_related('site'),
label='Rack group',
null_label='-- None --',
widget=APISelectMultiple(
api_url="/api/dcim/rack-groups/",
null_option=True,
)
)
class RackReservationBulkEditForm(BootstrapMixin, BulkEditForm): class RackReservationBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
queryset=RackReservation.objects.all(), queryset=RackReservation.objects.all(),
@ -728,6 +700,31 @@ class RackReservationBulkEditForm(BootstrapMixin, BulkEditForm):
nullable_fields = [] nullable_fields = []
class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm):
field_order = ['q', 'site', 'group_id', 'tenant_group', 'tenant']
q = forms.CharField(
required=False,
label='Search'
)
site = FilterChoiceField(
queryset=Site.objects.all(),
to_field_name='slug',
widget=APISelectMultiple(
api_url="/api/dcim/sites/",
value_field="slug",
)
)
group_id = FilterChoiceField(
queryset=RackGroup.objects.select_related('site'),
label='Rack group',
null_label='-- None --',
widget=APISelectMultiple(
api_url="/api/dcim/rack-groups/",
null_option=True,
)
)
# #
# Manufacturers # Manufacturers
# #
@ -1622,8 +1619,10 @@ class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Device model = Device
# Order the form fields, fields not listed are appended field_order = [
field_order = ['q', 'region', 'site', 'rack_group_id', 'rack_id', 'role'] 'q', 'region', 'site', 'rack_group_id', 'rack_id', 'status', 'role', 'tenant_group', 'tenant',
'manufacturer_id', 'device_type_id', 'mac_address', 'has_primary_ip',
]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -3074,9 +3073,31 @@ class VirtualChassisFilterForm(BootstrapMixin, CustomFieldFilterForm):
site = FilterChoiceField( site = FilterChoiceField(
queryset=Site.objects.all(), queryset=Site.objects.all(),
to_field_name='slug', to_field_name='slug',
widget=APISelectMultiple(
api_url="/api/dcim/sites/",
value_field="slug",
)
)
tenant_group = FilterChoiceField(
queryset=TenantGroup.objects.all(),
to_field_name='slug',
null_label='-- None --',
widget=APISelectMultiple(
api_url="/api/tenancy/tenant-groups/",
value_field="slug",
null_option=True,
filter_for={
'tenant': 'group'
}
)
) )
tenant = FilterChoiceField( tenant = FilterChoiceField(
queryset=Tenant.objects.all(), queryset=Tenant.objects.all(),
to_field_name='slug', to_field_name='slug',
null_label='-- None --', null_label='-- None --',
widget=APISelectMultiple(
api_url="/api/tenancy/tenants/",
value_field="slug",
null_option=True,
)
) )

View File

@ -4,7 +4,7 @@ from django.db.models import Q
from taggit.models import Tag from taggit.models import Tag
from dcim.models import DeviceRole, Platform, Region, Site from dcim.models import DeviceRole, Platform, Region, Site
from tenancy.filterset import TenancyFilterSet from tenancy.models import Tenant, TenantGroup
from .constants import CF_FILTER_DISABLED, CF_FILTER_EXACT, CF_TYPE_BOOLEAN, CF_TYPE_SELECT from .constants import CF_FILTER_DISABLED, CF_FILTER_EXACT, CF_TYPE_BOOLEAN, CF_TYPE_SELECT
from .models import ConfigContext, CustomField, Graph, ExportTemplate, ObjectChange, TopologyMap from .models import ConfigContext, CustomField, Graph, ExportTemplate, ObjectChange, TopologyMap
@ -122,7 +122,7 @@ class TopologyMapFilter(django_filters.FilterSet):
fields = ['name', 'slug'] fields = ['name', 'slug']
class ConfigContextFilter(TenancyFilterSet, django_filters.FilterSet): class ConfigContextFilter(django_filters.FilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label='Search', label='Search',
@ -171,6 +171,28 @@ class ConfigContextFilter(TenancyFilterSet, django_filters.FilterSet):
to_field_name='slug', to_field_name='slug',
label='Platform (slug)', label='Platform (slug)',
) )
tenant_group_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups',
queryset=TenantGroup.objects.all(),
label='Tenant group',
)
tenant_group = django_filters.ModelMultipleChoiceFilter(
field_name='tenant_groups__slug',
queryset=TenantGroup.objects.all(),
to_field_name='slug',
label='Tenant group (slug)',
)
tenant_id = django_filters.ModelMultipleChoiceFilter(
field_name='tenants',
queryset=Tenant.objects.all(),
label='Tenant',
)
tenant = django_filters.ModelMultipleChoiceFilter(
field_name='tenants__slug',
queryset=Tenant.objects.all(),
to_field_name='slug',
label='Tenant (slug)',
)
class Meta: class Meta:
model = ConfigContext model = ConfigContext

View File

@ -8,7 +8,7 @@ from taggit.forms import TagField
from taggit.models import Tag from taggit.models import Tag
from dcim.models import DeviceRole, Platform, Region, Site from dcim.models import DeviceRole, Platform, Region, Site
from tenancy.formset import TenancyFilterForm from tenancy.models import Tenant, TenantGroup
from utilities.forms import ( from utilities.forms import (
add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ContentTypeSelect, add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ContentTypeSelect,
FilterChoiceField, LaxURLField, JSONField, SlugField, FilterChoiceField, LaxURLField, JSONField, SlugField,
@ -274,7 +274,7 @@ class ConfigContextBulkEditForm(BootstrapMixin, BulkEditForm):
] ]
class ConfigContextFilterForm(TenancyFilterForm, BootstrapMixin, forms.Form): class ConfigContextFilterForm(BootstrapMixin, forms.Form):
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -311,10 +311,22 @@ class ConfigContextFilterForm(TenancyFilterForm, BootstrapMixin, forms.Form):
value_field="slug", value_field="slug",
) )
) )
tenant_group = FilterChoiceField(
class Meta: queryset=TenantGroup.objects.all(),
# Order the form fields, fields not listed are appended to_field_name='slug',
field_order = ['q', 'type', 'provider', 'status'] widget=APISelectMultiple(
api_url="/api/tenancy/tenant-groups/",
value_field="slug",
)
)
tenant = FilterChoiceField(
queryset=Tenant.objects.all(),
to_field_name='slug',
widget=APISelectMultiple(
api_url="/api/tenancy/tenants/",
value_field="slug",
)
)
# #

View File

@ -6,14 +6,14 @@ from netaddr.core import AddrFormatError
from dcim.models import Site, Device, Interface from dcim.models import Site, Device, Interface
from extras.filters import CustomFieldFilterSet from extras.filters import CustomFieldFilterSet
from tenancy.filterset import TenancyFilterSet from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter
from virtualization.models import VirtualMachine from virtualization.models import VirtualMachine
from .constants import IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, PREFIX_STATUS_CHOICES, VLAN_STATUS_CHOICES from .constants import IPADDRESS_ROLE_CHOICES, IPADDRESS_STATUS_CHOICES, PREFIX_STATUS_CHOICES, VLAN_STATUS_CHOICES
from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF
class VRFFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class VRFFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -49,7 +49,7 @@ class RIRFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug', 'is_private'] fields = ['name', 'slug', 'is_private']
class AggregateFilter(CustomFieldFilterSet, django_filters.FilterSet): class AggregateFilter(CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -97,7 +97,7 @@ class RoleFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug'] fields = ['name', 'slug']
class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -234,7 +234,7 @@ class PrefixFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.Filter
return queryset.filter(prefix__net_mask_length=value) return queryset.filter(prefix__net_mask_length=value)
class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'
@ -364,7 +364,7 @@ class VLANGroupFilter(NameSlugSearchFilterSet):
fields = ['name', 'slug'] fields = ['name', 'slug']
class VLANFilter(TenancyFilterSet, CustomFieldFilterSet, django_filters.FilterSet): class VLANFilter(TenancyFilterSet, CustomFieldFilterSet):
id__in = NumericInFilter( id__in = NumericInFilter(
field_name='id', field_name='id',
lookup_expr='in' lookup_expr='in'

View File

@ -100,8 +100,7 @@ class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm
class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VRFFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VRF model = VRF
# Order the form fields, fields not listed are appended field_order = ['q', 'tenant_group', 'tenant']
field_order = ['q']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -492,8 +491,10 @@ class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditF
class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class PrefixFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = Prefix model = Prefix
# Order the form fields, fields not listed are appended field_order = [
field_order = ['q', 'within_include', 'family', 'mask_length', 'vrf'] 'q', 'within_include', 'family', 'mask_length', 'vrf_id', 'status', 'site', 'role', 'tenant_group', 'tenant',
'is_pool', 'expand',
]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -931,8 +932,9 @@ class IPAddressAssignForm(BootstrapMixin, forms.Form):
class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class IPAddressFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = IPAddress model = IPAddress
# Order the form fields, fields not listed are appended field_order = [
field_order = ['q', 'parent', 'family', 'mask_length', 'vrf'] 'q', 'parent', 'family', 'mask_length', 'vrf_id', 'status', 'role', 'tenant_group', 'tenant',
]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'
@ -1200,8 +1202,7 @@ class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor
class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VLANFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VLAN model = VLAN
# Order the form fields, fields not listed are appended field_order = ['q', 'site', 'group_id', 'status', 'role', 'tenant_group', 'tenant']
field_order = ['q', 'site', 'group_id']
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'

View File

@ -118,6 +118,7 @@ class TenantFilterForm(BootstrapMixin, CustomFieldFilterForm):
# #
# Tenancy form extension # Tenancy form extension
# #
class TenancyForm(ChainedFieldsMixin, forms.Form): class TenancyForm(ChainedFieldsMixin, forms.Form):
tenant_group = forms.ModelChoiceField( tenant_group = forms.ModelChoiceField(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),

View File

@ -1,12 +1,11 @@
import django_filters import django_filters
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q from django.db.models import Q
from netaddr import EUI from netaddr import EUI
from netaddr.core import AddrFormatError from netaddr.core import AddrFormatError
from dcim.models import DeviceRole, Interface, Platform, Region, Site from dcim.models import DeviceRole, Interface, Platform, Region, Site
from extras.filters import CustomFieldFilterSet from extras.filters import CustomFieldFilterSet
from tenancy.filterset import TenancyFilterSet from tenancy.filtersets import TenancyFilterSet
from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter from utilities.filters import NameSlugSearchFilterSet, NumericInFilter, TagFilter, TreeNodeMultipleChoiceFilter
from .constants import VM_STATUS_CHOICES from .constants import VM_STATUS_CHOICES
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine

View File

@ -9,7 +9,7 @@ from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomField
from ipam.models import IPAddress from ipam.models import IPAddress
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from tenancy.formset import TenancyFilterForm from tenancy.formset import TenancyFilterForm
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant
from utilities.forms import ( from utilities.forms import (
add_blank_choice, APISelect, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, add_blank_choice, APISelect, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
ChainedFieldsMixin, ChainedModelChoiceField, ChainedModelMultipleChoiceField, CommentField, ComponentForm, ChainedFieldsMixin, ChainedModelChoiceField, ChainedModelMultipleChoiceField, CommentField, ComponentForm,
@ -337,8 +337,8 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
class Meta: class Meta:
model = VirtualMachine model = VirtualMachine
fields = [ fields = [
'name', 'status', 'cluster_group', 'cluster', 'role', 'tenant_group', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'name', 'status', 'cluster_group', 'cluster', 'role', 'tenant_group', 'tenant', 'platform', 'primary_ip4',
'vcpus', 'memory', 'disk', 'comments', 'tags', 'local_context_data', 'primary_ip6', 'vcpus', 'memory', 'disk', 'comments', 'tags', 'local_context_data',
] ]
help_texts = { help_texts = {
'local_context_data': "Local config context data overwrites all sources contexts in the final rendered " 'local_context_data': "Local config context data overwrites all sources contexts in the final rendered "
@ -523,8 +523,10 @@ class VirtualMachineBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldB
class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): class VirtualMachineFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
model = VirtualMachine model = VirtualMachine
# Order the form fields, fields not listed are appended field_order = [
field_order = ['q', 'cluster_group', 'cluster_type', 'cluster_id', 'region', 'site'] 'q', 'cluster_group', 'cluster_type', 'cluster_id', 'status', 'role', 'region', 'site', 'tenant_group',
'tenant', 'platform',
]
q = forms.CharField( q = forms.CharField(
required=False, required=False,
label='Search' label='Search'