mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Fixes #9657: Fix filtering for custom fields and webhooks in the UI
This commit is contained in:
@ -32,6 +32,9 @@ class WebhookFilterSet(BaseFilterSet):
|
||||
method='search',
|
||||
label='Search',
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
)
|
||||
content_types = ContentTypeFilter()
|
||||
http_method = django_filters.MultipleChoiceFilter(
|
||||
choices=WebhookHttpMethodChoices
|
||||
@ -40,8 +43,8 @@ class WebhookFilterSet(BaseFilterSet):
|
||||
class Meta:
|
||||
model = Webhook
|
||||
fields = [
|
||||
'id', 'content_types', 'name', 'type_create', 'type_update', 'type_delete', 'payload_url', 'enabled',
|
||||
'http_method', 'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
|
||||
'id', 'name', 'type_create', 'type_update', 'type_delete', 'payload_url', 'enabled', 'http_method',
|
||||
'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
|
||||
]
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
@ -58,11 +61,17 @@ class CustomFieldFilterSet(BaseFilterSet):
|
||||
method='search',
|
||||
label='Search',
|
||||
)
|
||||
type = django_filters.MultipleChoiceFilter(
|
||||
choices=CustomFieldTypeChoices
|
||||
)
|
||||
content_type_id = MultiValueNumberFilter(
|
||||
field_name='content_types__id'
|
||||
)
|
||||
content_types = ContentTypeFilter()
|
||||
|
||||
class Meta:
|
||||
model = CustomField
|
||||
fields = ['id', 'content_types', 'name', 'required', 'filter_logic', 'weight', 'description']
|
||||
fields = ['id', 'name', 'required', 'filter_logic', 'weight', 'description']
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
|
@ -32,12 +32,13 @@ __all__ = (
|
||||
class CustomFieldFilterForm(FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
('Attributes', ('type', 'content_types', 'weight', 'required')),
|
||||
('Attributes', ('type', 'content_type_id', 'weight', 'required')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
content_type_id = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('custom_fields'),
|
||||
required=False
|
||||
required=False,
|
||||
label='Object type'
|
||||
)
|
||||
type = MultipleChoiceField(
|
||||
choices=CustomFieldTypeChoices,
|
||||
@ -110,13 +111,14 @@ class ExportTemplateFilterForm(FilterForm):
|
||||
class WebhookFilterForm(FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
('Attributes', ('content_types', 'http_method', 'enabled')),
|
||||
('Attributes', ('content_type_id', 'http_method', 'enabled')),
|
||||
('Events', ('type_create', 'type_update', 'type_delete')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
content_type_id = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('webhooks'),
|
||||
required=False
|
||||
required=False,
|
||||
label='Object type'
|
||||
)
|
||||
http_method = MultipleChoiceField(
|
||||
choices=WebhookHttpMethodChoices,
|
||||
|
@ -7,7 +7,9 @@ from django.test import TestCase
|
||||
|
||||
from circuits.models import Provider
|
||||
from dcim.models import DeviceRole, DeviceType, Manufacturer, Platform, Rack, Region, Site, SiteGroup
|
||||
from extras.choices import JournalEntryKindChoices, ObjectChangeActionChoices
|
||||
from extras.choices import (
|
||||
CustomFieldTypeChoices, CustomFieldFilterLogicChoices, JournalEntryKindChoices, ObjectChangeActionChoices,
|
||||
)
|
||||
from extras.filtersets import *
|
||||
from extras.models import *
|
||||
from ipam.models import IPAddress
|
||||
@ -16,6 +18,65 @@ from utilities.testing import BaseFilterSetTests, ChangeLoggedFilterSetTests, cr
|
||||
from virtualization.models import Cluster, ClusterGroup, ClusterType
|
||||
|
||||
|
||||
class CustomFieldTestCase(TestCase, BaseFilterSetTests):
|
||||
queryset = CustomField.objects.all()
|
||||
filterset = CustomFieldFilterSet
|
||||
|
||||
@classmethod
|
||||
def setUpTestData(cls):
|
||||
content_types = ContentType.objects.filter(model__in=['site', 'rack', 'device'])
|
||||
|
||||
custom_fields = (
|
||||
CustomField(
|
||||
name='Custom Field 1',
|
||||
type=CustomFieldTypeChoices.TYPE_TEXT,
|
||||
required=True,
|
||||
weight=100,
|
||||
filter_logic=CustomFieldFilterLogicChoices.FILTER_LOOSE
|
||||
),
|
||||
CustomField(
|
||||
name='Custom Field 2',
|
||||
type=CustomFieldTypeChoices.TYPE_INTEGER,
|
||||
required=False,
|
||||
weight=200,
|
||||
filter_logic=CustomFieldFilterLogicChoices.FILTER_EXACT
|
||||
),
|
||||
CustomField(
|
||||
name='Custom Field 3',
|
||||
type=CustomFieldTypeChoices.TYPE_BOOLEAN,
|
||||
required=False,
|
||||
weight=300,
|
||||
filter_logic=CustomFieldFilterLogicChoices.FILTER_DISABLED
|
||||
),
|
||||
)
|
||||
CustomField.objects.bulk_create(custom_fields)
|
||||
custom_fields[0].content_types.add(content_types[0])
|
||||
custom_fields[1].content_types.add(content_types[1])
|
||||
custom_fields[2].content_types.add(content_types[2])
|
||||
|
||||
def test_name(self):
|
||||
params = {'name': ['Custom Field 1', 'Custom Field 2']}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_content_types(self):
|
||||
params = {'content_types': 'dcim.site'}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
params = {'content_type_id': [ContentType.objects.get_for_model(Site).pk]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_required(self):
|
||||
params = {'required': True}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_weight(self):
|
||||
params = {'weight': [100, 200]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_filter_logic(self):
|
||||
params = {'filter_logic': CustomFieldFilterLogicChoices.FILTER_LOOSE}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
|
||||
class WebhookTestCase(TestCase, BaseFilterSetTests):
|
||||
queryset = Webhook.objects.all()
|
||||
filterset = WebhookFilterSet
|
||||
@ -62,6 +123,8 @@ class WebhookTestCase(TestCase, BaseFilterSetTests):
|
||||
def test_content_types(self):
|
||||
params = {'content_types': 'dcim.site'}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
params = {'content_type_id': [ContentType.objects.get_for_model(Site).pk]}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1)
|
||||
|
||||
def test_type_create(self):
|
||||
params = {'type_create': True}
|
||||
|
Reference in New Issue
Block a user