mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 12:06:53 -06:00
Fixes #8645; Allow filtering on core models in the UI
This commit is contained in:
parent
4913d7ee39
commit
bf22b820bf
@ -5,7 +5,7 @@ from dcim.filtersets import CableTerminationFilterSet
|
|||||||
from dcim.models import Region, Site, SiteGroup
|
from dcim.models import Region, Site, SiteGroup
|
||||||
from extras.filters import TagFilter
|
from extras.filters import TagFilter
|
||||||
from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
|
from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
|
||||||
from tenancy.filtersets import TenancyFilterSet
|
from tenancy.filtersets import (TenancyFilterSet, ContactModelFilterSet)
|
||||||
from utilities.filters import TreeNodeMultipleChoiceFilter
|
from utilities.filters import TreeNodeMultipleChoiceFilter
|
||||||
from .choices import *
|
from .choices import *
|
||||||
from .models import *
|
from .models import *
|
||||||
@ -19,7 +19,7 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProviderFilterSet(PrimaryModelFilterSet):
|
class ProviderFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
@ -118,7 +118,7 @@ class CircuitTypeFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug']
|
fields = ['id', 'name', 'slug']
|
||||||
|
|
||||||
|
|
||||||
class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
|
@ -5,7 +5,7 @@ from circuits.choices import CircuitStatusChoices
|
|||||||
from circuits.models import *
|
from circuits.models import *
|
||||||
from dcim.models import Region, Site, SiteGroup
|
from dcim.models import Region, Site, SiteGroup
|
||||||
from extras.forms import CustomFieldModelFilterForm
|
from extras.forms import CustomFieldModelFilterForm
|
||||||
from tenancy.forms import TenancyFilterForm
|
from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
|
||||||
from utilities.forms import DynamicModelMultipleChoiceField, StaticSelectMultiple, TagFilterField
|
from utilities.forms import DynamicModelMultipleChoiceField, StaticSelectMultiple, TagFilterField
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -16,12 +16,13 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ProviderFilterForm(CustomFieldModelFilterForm):
|
class ProviderFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Provider
|
model = Provider
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['asn'],
|
['asn'],
|
||||||
|
['contact', 'contact_role']
|
||||||
]
|
]
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -68,7 +69,7 @@ class CircuitTypeFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Circuit
|
model = Circuit
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
@ -76,6 +77,7 @@ class CircuitFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
['type_id', 'status', 'commit_rate'],
|
['type_id', 'status', 'commit_rate'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
['contact', 'contact_role']
|
||||||
]
|
]
|
||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=CircuitType.objects.all(),
|
queryset=CircuitType.objects.all(),
|
||||||
|
@ -7,8 +7,8 @@ from ipam.models import ASN
|
|||||||
from netbox.filtersets import (
|
from netbox.filtersets import (
|
||||||
BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
|
BaseFilterSet, ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
|
||||||
)
|
)
|
||||||
from tenancy.filtersets import TenancyFilterSet
|
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
|
||||||
from tenancy.models import Tenant
|
from tenancy.models import *
|
||||||
from utilities.choices import ColorChoices
|
from utilities.choices import ColorChoices
|
||||||
from utilities.filters import (
|
from utilities.filters import (
|
||||||
ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
|
ContentTypeFilter, MultiValueCharFilter, MultiValueMACAddressFilter, MultiValueNumberFilter, MultiValueWWNFilter,
|
||||||
@ -62,7 +62,7 @@ __all__ = (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RegionFilterSet(OrganizationalModelFilterSet):
|
class RegionFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
|
||||||
parent_id = django_filters.ModelMultipleChoiceFilter(
|
parent_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
label='Parent region (ID)',
|
label='Parent region (ID)',
|
||||||
@ -80,7 +80,7 @@ class RegionFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'description']
|
fields = ['id', 'name', 'slug', 'description']
|
||||||
|
|
||||||
|
|
||||||
class SiteGroupFilterSet(OrganizationalModelFilterSet):
|
class SiteGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
|
||||||
parent_id = django_filters.ModelMultipleChoiceFilter(
|
parent_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
label='Parent site group (ID)',
|
label='Parent site group (ID)',
|
||||||
@ -98,7 +98,7 @@ class SiteGroupFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'description']
|
fields = ['id', 'name', 'slug', 'description']
|
||||||
|
|
||||||
|
|
||||||
class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
@ -167,7 +167,7 @@ class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
|||||||
return queryset.filter(qs_filter)
|
return queryset.filter(qs_filter)
|
||||||
|
|
||||||
|
|
||||||
class LocationFilterSet(TenancyFilterSet, OrganizationalModelFilterSet):
|
class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, OrganizationalModelFilterSet):
|
||||||
region_id = TreeNodeMultipleChoiceFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
field_name='site__region',
|
field_name='site__region',
|
||||||
@ -240,7 +240,7 @@ class RackRoleFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'color']
|
fields = ['id', 'name', 'slug', 'color']
|
||||||
|
|
||||||
|
|
||||||
class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
@ -398,7 +398,7 @@ class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ManufacturerFilterSet(OrganizationalModelFilterSet):
|
class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
|
||||||
tag = TagFilter()
|
tag = TagFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -608,7 +608,7 @@ class PlatformFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
|
fields = ['id', 'name', 'slug', 'napalm_driver', 'description']
|
||||||
|
|
||||||
|
|
||||||
class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, LocalConfigContextFilterSet):
|
class DeviceFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
@ -1289,7 +1289,7 @@ class CableFilterSet(TenancyFilterSet, PrimaryModelFilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
|
||||||
class PowerPanelFilterSet(PrimaryModelFilterSet):
|
class PowerPanelFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
|
@ -5,9 +5,12 @@ from django.utils.translation import gettext as _
|
|||||||
from dcim.choices import *
|
from dcim.choices import *
|
||||||
from dcim.constants import *
|
from dcim.constants import *
|
||||||
from dcim.models import *
|
from dcim.models import *
|
||||||
|
from tenancy.models import *
|
||||||
from extras.forms import CustomFieldModelFilterForm, LocalConfigContextFilterForm
|
from extras.forms import CustomFieldModelFilterForm, LocalConfigContextFilterForm
|
||||||
from ipam.models import ASN
|
from ipam.models import ASN
|
||||||
from tenancy.forms import TenancyFilterForm
|
from tenancy.forms import (
|
||||||
|
TenancyFilterForm, ContactModelFilterForm
|
||||||
|
)
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm, StaticSelect,
|
APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm, StaticSelect,
|
||||||
StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
|
StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
|
||||||
@ -98,7 +101,7 @@ class DeviceComponentFilterForm(CustomFieldModelFilterForm):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RegionFilterForm(CustomFieldModelFilterForm):
|
class RegionFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Region
|
model = Region
|
||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -108,7 +111,7 @@ class RegionFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class SiteGroupFilterForm(CustomFieldModelFilterForm):
|
class SiteGroupFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = SiteGroup
|
model = SiteGroup
|
||||||
parent_id = DynamicModelMultipleChoiceField(
|
parent_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
@ -118,13 +121,14 @@ class SiteGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class SiteFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
class SiteFilterForm(TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Site
|
model = Site
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
['status', 'region_id', 'group_id'],
|
['status', 'region_id', 'group_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
['asn_id']
|
['asn_id'],
|
||||||
|
['contact', 'contact_role'],
|
||||||
]
|
]
|
||||||
status = forms.MultipleChoiceField(
|
status = forms.MultipleChoiceField(
|
||||||
choices=SiteStatusChoices,
|
choices=SiteStatusChoices,
|
||||||
@ -148,13 +152,13 @@ class SiteFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
)
|
)
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
class LocationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|
||||||
model = Location
|
model = Location
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
['region_id', 'site_group_id', 'site_id', 'parent_id'],
|
['region_id', 'site_group_id', 'site_id', 'parent_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
['contact', 'contact_role'],
|
||||||
]
|
]
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -192,7 +196,7 @@ class RackRoleFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Rack
|
model = Rack
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
@ -200,6 +204,7 @@ class RackFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
['status', 'role_id'],
|
['status', 'role_id'],
|
||||||
['type', 'width', 'serial', 'asset_tag'],
|
['type', 'width', 'serial', 'asset_tag'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
['contact', 'contact_role']
|
||||||
]
|
]
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -303,7 +308,7 @@ class RackReservationFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class ManufacturerFilterForm(CustomFieldModelFilterForm):
|
class ManufacturerFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Manufacturer
|
model = Manufacturer
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
@ -390,7 +395,7 @@ class PlatformFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldModelFilterForm):
|
class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Device
|
model = Device
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
@ -402,6 +407,7 @@ class DeviceFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFi
|
|||||||
'has_primary_ip', 'virtual_chassis_member', 'console_ports', 'console_server_ports', 'power_ports',
|
'has_primary_ip', 'virtual_chassis_member', 'console_ports', 'console_server_ports', 'power_ports',
|
||||||
'power_outlets', 'interfaces', 'pass_through_ports', 'local_context_data',
|
'power_outlets', 'interfaces', 'pass_through_ports', 'local_context_data',
|
||||||
],
|
],
|
||||||
|
['contact', 'contact_role'],
|
||||||
]
|
]
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
@ -636,11 +642,12 @@ class CableFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class PowerPanelFilterForm(CustomFieldModelFilterForm):
|
class PowerPanelFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = PowerPanel
|
model = PowerPanel
|
||||||
field_groups = (
|
field_groups = (
|
||||||
('q', 'tag'),
|
('q', 'tag'),
|
||||||
('region_id', 'site_group_id', 'site_id', 'location_id')
|
('region_id', 'site_group_id', 'site_id', 'location_id'),
|
||||||
|
('contact', 'contact_role')
|
||||||
)
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
|
@ -15,92 +15,7 @@ __all__ = (
|
|||||||
'TenancyFilterSet',
|
'TenancyFilterSet',
|
||||||
'TenantFilterSet',
|
'TenantFilterSet',
|
||||||
'TenantGroupFilterSet',
|
'TenantGroupFilterSet',
|
||||||
)
|
'ContactModelFilterSet'
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Tenancy
|
|
||||||
#
|
|
||||||
|
|
||||||
class TenantGroupFilterSet(OrganizationalModelFilterSet):
|
|
||||||
parent_id = django_filters.ModelMultipleChoiceFilter(
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
label='Tenant group (ID)',
|
|
||||||
)
|
|
||||||
parent = django_filters.ModelMultipleChoiceFilter(
|
|
||||||
field_name='parent__slug',
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
to_field_name='slug',
|
|
||||||
label='Tenant group (slug)',
|
|
||||||
)
|
|
||||||
tag = TagFilter()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = TenantGroup
|
|
||||||
fields = ['id', 'name', 'slug', 'description']
|
|
||||||
|
|
||||||
|
|
||||||
class TenantFilterSet(PrimaryModelFilterSet):
|
|
||||||
q = django_filters.CharFilter(
|
|
||||||
method='search',
|
|
||||||
label='Search',
|
|
||||||
)
|
|
||||||
group_id = TreeNodeMultipleChoiceFilter(
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
field_name='group',
|
|
||||||
lookup_expr='in',
|
|
||||||
label='Tenant group (ID)',
|
|
||||||
)
|
|
||||||
group = TreeNodeMultipleChoiceFilter(
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
field_name='group',
|
|
||||||
lookup_expr='in',
|
|
||||||
to_field_name='slug',
|
|
||||||
label='Tenant group (slug)',
|
|
||||||
)
|
|
||||||
tag = TagFilter()
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = Tenant
|
|
||||||
fields = ['id', 'name', 'slug']
|
|
||||||
|
|
||||||
def search(self, queryset, name, value):
|
|
||||||
if not value.strip():
|
|
||||||
return queryset
|
|
||||||
return queryset.filter(
|
|
||||||
Q(name__icontains=value) |
|
|
||||||
Q(slug__icontains=value) |
|
|
||||||
Q(description__icontains=value) |
|
|
||||||
Q(comments__icontains=value)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TenancyFilterSet(django_filters.FilterSet):
|
|
||||||
"""
|
|
||||||
An inheritable FilterSet for models which support Tenant assignment.
|
|
||||||
"""
|
|
||||||
tenant_group_id = TreeNodeMultipleChoiceFilter(
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
field_name='tenant__group',
|
|
||||||
lookup_expr='in',
|
|
||||||
label='Tenant Group (ID)',
|
|
||||||
)
|
|
||||||
tenant_group = TreeNodeMultipleChoiceFilter(
|
|
||||||
queryset=TenantGroup.objects.all(),
|
|
||||||
field_name='tenant__group',
|
|
||||||
to_field_name='slug',
|
|
||||||
lookup_expr='in',
|
|
||||||
label='Tenant Group (slug)',
|
|
||||||
)
|
|
||||||
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
|
||||||
queryset=Tenant.objects.all(),
|
|
||||||
label='Tenant (ID)',
|
|
||||||
)
|
|
||||||
tenant = django_filters.ModelMultipleChoiceFilter(
|
|
||||||
queryset=Tenant.objects.all(),
|
|
||||||
field_name='tenant__slug',
|
|
||||||
to_field_name='slug',
|
|
||||||
label='Tenant (slug)',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -191,3 +106,102 @@ class ContactAssignmentFilterSet(ChangeLoggedModelFilterSet):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = ContactAssignment
|
model = ContactAssignment
|
||||||
fields = ['id', 'content_type_id', 'object_id', 'priority']
|
fields = ['id', 'content_type_id', 'object_id', 'priority']
|
||||||
|
|
||||||
|
|
||||||
|
class ContactModelFilterSet(django_filters.FilterSet):
|
||||||
|
contact = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
field_name='contacts__contact',
|
||||||
|
queryset=Contact.objects.all(),
|
||||||
|
label='Contact',
|
||||||
|
)
|
||||||
|
contact_role = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
field_name='contacts__role',
|
||||||
|
queryset=ContactRole.objects.all(),
|
||||||
|
label='Contact Role'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tenancy
|
||||||
|
#
|
||||||
|
|
||||||
|
class TenantGroupFilterSet(OrganizationalModelFilterSet):
|
||||||
|
parent_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
label='Tenant group (ID)',
|
||||||
|
)
|
||||||
|
parent = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
field_name='parent__slug',
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Tenant group (slug)',
|
||||||
|
)
|
||||||
|
tag = TagFilter()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = TenantGroup
|
||||||
|
fields = ['id', 'name', 'slug', 'description']
|
||||||
|
|
||||||
|
|
||||||
|
class TenantFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
|
group_id = TreeNodeMultipleChoiceFilter(
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
field_name='group',
|
||||||
|
lookup_expr='in',
|
||||||
|
label='Tenant group (ID)',
|
||||||
|
)
|
||||||
|
group = TreeNodeMultipleChoiceFilter(
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
field_name='group',
|
||||||
|
lookup_expr='in',
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Tenant group (slug)',
|
||||||
|
)
|
||||||
|
tag = TagFilter()
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Tenant
|
||||||
|
fields = ['id', 'name', 'slug']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(slug__icontains=value) |
|
||||||
|
Q(description__icontains=value) |
|
||||||
|
Q(comments__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TenancyFilterSet(django_filters.FilterSet):
|
||||||
|
"""
|
||||||
|
An inheritable FilterSet for models which support Tenant assignment.
|
||||||
|
"""
|
||||||
|
tenant_group_id = TreeNodeMultipleChoiceFilter(
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
field_name='tenant__group',
|
||||||
|
lookup_expr='in',
|
||||||
|
label='Tenant Group (ID)',
|
||||||
|
)
|
||||||
|
tenant_group = TreeNodeMultipleChoiceFilter(
|
||||||
|
queryset=TenantGroup.objects.all(),
|
||||||
|
field_name='tenant__group',
|
||||||
|
to_field_name='slug',
|
||||||
|
lookup_expr='in',
|
||||||
|
label='Tenant Group (slug)',
|
||||||
|
)
|
||||||
|
tenant_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=Tenant.objects.all(),
|
||||||
|
label='Tenant (ID)',
|
||||||
|
)
|
||||||
|
tenant = django_filters.ModelMultipleChoiceFilter(
|
||||||
|
queryset=Tenant.objects.all(),
|
||||||
|
field_name='tenant__slug',
|
||||||
|
to_field_name='slug',
|
||||||
|
label='Tenant (slug)',
|
||||||
|
)
|
||||||
|
@ -2,6 +2,7 @@ from django.utils.translation import gettext as _
|
|||||||
|
|
||||||
from extras.forms import CustomFieldModelFilterForm
|
from extras.forms import CustomFieldModelFilterForm
|
||||||
from tenancy.models import *
|
from tenancy.models import *
|
||||||
|
from tenancy.forms import ContactModelFilterForm
|
||||||
from utilities.forms import DynamicModelMultipleChoiceField, TagFilterField
|
from utilities.forms import DynamicModelMultipleChoiceField, TagFilterField
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -27,11 +28,12 @@ class TenantGroupFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class TenantFilterForm(CustomFieldModelFilterForm):
|
class TenantFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Tenant
|
model = Tenant
|
||||||
field_groups = (
|
field_groups = (
|
||||||
('q', 'tag'),
|
('q', 'tag'),
|
||||||
('group_id',),
|
('group_id',),
|
||||||
|
('contact', 'contact_role')
|
||||||
)
|
)
|
||||||
group_id = DynamicModelMultipleChoiceField(
|
group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=TenantGroup.objects.all(),
|
queryset=TenantGroup.objects.all(),
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from tenancy.models import Tenant, TenantGroup
|
from tenancy.models import *
|
||||||
from utilities.forms import DynamicModelChoiceField, DynamicModelMultipleChoiceField
|
from utilities.forms import DynamicModelChoiceField, DynamicModelMultipleChoiceField
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'TenancyForm',
|
'TenancyForm',
|
||||||
'TenancyFilterForm',
|
'TenancyFilterForm',
|
||||||
|
'ContactModelFilterForm'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -44,3 +45,16 @@ class TenancyFilterForm(forms.Form):
|
|||||||
},
|
},
|
||||||
label=_('Tenant')
|
label=_('Tenant')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ContactModelFilterForm(forms.Form):
|
||||||
|
contact = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=Contact.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Contact')
|
||||||
|
)
|
||||||
|
contact_role = DynamicModelMultipleChoiceField(
|
||||||
|
queryset=ContactRole.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Contact Role')
|
||||||
|
)
|
@ -5,7 +5,7 @@ from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
|
|||||||
from extras.filters import TagFilter
|
from extras.filters import TagFilter
|
||||||
from extras.filtersets import LocalConfigContextFilterSet
|
from extras.filtersets import LocalConfigContextFilterSet
|
||||||
from netbox.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
|
from netbox.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
|
||||||
from tenancy.filtersets import TenancyFilterSet
|
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
|
||||||
from utilities.filters import MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
|
from utilities.filters import MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
|
||||||
from .choices import *
|
from .choices import *
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||||
@ -27,7 +27,7 @@ class ClusterTypeFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'description']
|
fields = ['id', 'name', 'slug', 'description']
|
||||||
|
|
||||||
|
|
||||||
class ClusterGroupFilterSet(OrganizationalModelFilterSet):
|
class ClusterGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
|
||||||
tag = TagFilter()
|
tag = TagFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
@ -35,7 +35,7 @@ class ClusterGroupFilterSet(OrganizationalModelFilterSet):
|
|||||||
fields = ['id', 'name', 'slug', 'description']
|
fields = ['id', 'name', 'slug', 'description']
|
||||||
|
|
||||||
|
|
||||||
class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
@ -111,7 +111,7 @@ class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineFilterSet(PrimaryModelFilterSet, TenancyFilterSet, LocalConfigContextFilterSet):
|
class VirtualMachineFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet, LocalConfigContextFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
method='search',
|
method='search',
|
||||||
label='Search',
|
label='Search',
|
||||||
|
@ -3,7 +3,7 @@ from django.utils.translation import gettext as _
|
|||||||
|
|
||||||
from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
|
from dcim.models import DeviceRole, Platform, Region, Site, SiteGroup
|
||||||
from extras.forms import CustomFieldModelFilterForm, LocalConfigContextFilterForm
|
from extras.forms import CustomFieldModelFilterForm, LocalConfigContextFilterForm
|
||||||
from tenancy.forms import TenancyFilterForm
|
from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
|
||||||
from utilities.forms import (
|
from utilities.forms import (
|
||||||
DynamicModelMultipleChoiceField, StaticSelect, StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
|
DynamicModelMultipleChoiceField, StaticSelect, StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
|
||||||
)
|
)
|
||||||
@ -24,18 +24,19 @@ class ClusterTypeFilterForm(CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class ClusterGroupFilterForm(CustomFieldModelFilterForm):
|
class ClusterGroupFilterForm(ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = ClusterGroup
|
model = ClusterGroup
|
||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class ClusterFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
class ClusterFilterForm(TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = Cluster
|
model = Cluster
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
['group_id', 'type_id'],
|
['group_id', 'type_id'],
|
||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
['contact', 'contact_role'],
|
||||||
]
|
]
|
||||||
type_id = DynamicModelMultipleChoiceField(
|
type_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterType.objects.all(),
|
queryset=ClusterType.objects.all(),
|
||||||
@ -71,7 +72,7 @@ class ClusterFilterForm(TenancyFilterForm, CustomFieldModelFilterForm):
|
|||||||
tag = TagFilterField(model)
|
tag = TagFilterField(model)
|
||||||
|
|
||||||
|
|
||||||
class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, CustomFieldModelFilterForm):
|
class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, ContactModelFilterForm, CustomFieldModelFilterForm):
|
||||||
model = VirtualMachine
|
model = VirtualMachine
|
||||||
field_groups = [
|
field_groups = [
|
||||||
['q', 'tag'],
|
['q', 'tag'],
|
||||||
@ -79,6 +80,7 @@ class VirtualMachineFilterForm(LocalConfigContextFilterForm, TenancyFilterForm,
|
|||||||
['region_id', 'site_group_id', 'site_id'],
|
['region_id', 'site_group_id', 'site_id'],
|
||||||
['status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data'],
|
['status', 'role_id', 'platform_id', 'mac_address', 'has_primary_ip', 'local_context_data'],
|
||||||
['tenant_group_id', 'tenant_id'],
|
['tenant_group_id', 'tenant_id'],
|
||||||
|
['contact', 'contact_role'],
|
||||||
]
|
]
|
||||||
cluster_group_id = DynamicModelMultipleChoiceField(
|
cluster_group_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=ClusterGroup.objects.all(),
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
Loading…
Reference in New Issue
Block a user