mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-24 09:28:38 -06:00
Merge pull request #7824 from netbox-community/2101-q-filters
Closes #2101: Ensure all relevant models have a general purpose search filter
This commit is contained in:
commit
98cc36c458
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
|
* [#2101](https://github.com/netbox-community/netbox/issues/2101) - Add missing `q` filters for necessary models
|
||||||
* [#7803](https://github.com/netbox-community/netbox/issues/7803) - Improve live reloading of custom scripts
|
* [#7803](https://github.com/netbox-community/netbox/issues/7803) - Improve live reloading of custom scripts
|
||||||
* [#7810](https://github.com/netbox-community/netbox/issues/7810) - Add IEEE 802.15.1 interface type
|
* [#7810](https://github.com/netbox-community/netbox/issues/7810) - Add IEEE 802.15.1 interface type
|
||||||
|
|
||||||
|
@ -1394,6 +1394,10 @@ class PowerFeedFilterSet(PrimaryModelFilterSet, CableTerminationFilterSet, PathE
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConnectionFilterSet(BaseFilterSet):
|
class ConnectionFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
site_id = MultiValueNumberFilter(
|
site_id = MultiValueNumberFilter(
|
||||||
method='filter_connections',
|
method='filter_connections',
|
||||||
field_name='device__site_id'
|
field_name='device__site_id'
|
||||||
@ -1416,6 +1420,15 @@ class ConnectionFilterSet(BaseFilterSet):
|
|||||||
return queryset
|
return queryset
|
||||||
return queryset.filter(**{f'{name}__in': value})
|
return queryset.filter(**{f'{name}__in': value})
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
qs_filter = (
|
||||||
|
Q(device__name__icontains=value) |
|
||||||
|
Q(cable__label__icontains=value)
|
||||||
|
)
|
||||||
|
return queryset.filter(qs_filter)
|
||||||
|
|
||||||
|
|
||||||
class ConsoleConnectionFilterSet(ConnectionFilterSet):
|
class ConsoleConnectionFilterSet(ConnectionFilterSet):
|
||||||
|
|
||||||
|
@ -1068,6 +1068,11 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -1095,6 +1100,11 @@ class ConsoleConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
@ -1122,6 +1132,11 @@ class PowerConnectionFilterForm(BootstrapMixin, forms.Form):
|
|||||||
|
|
||||||
|
|
||||||
class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
class InterfaceConnectionFilterForm(BootstrapMixin, forms.Form):
|
||||||
|
q = forms.CharField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.TextInput(attrs={'placeholder': _('All Fields')}),
|
||||||
|
label=_('Search')
|
||||||
|
)
|
||||||
region_id = DynamicModelMultipleChoiceField(
|
region_id = DynamicModelMultipleChoiceField(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
required=False,
|
required=False,
|
||||||
|
@ -35,6 +35,10 @@ EXACT_FILTER_TYPES = (
|
|||||||
|
|
||||||
|
|
||||||
class WebhookFilterSet(BaseFilterSet):
|
class WebhookFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
content_types = ContentTypeFilter()
|
content_types = ContentTypeFilter()
|
||||||
http_method = django_filters.MultipleChoiceFilter(
|
http_method = django_filters.MultipleChoiceFilter(
|
||||||
choices=WebhookHttpMethodChoices
|
choices=WebhookHttpMethodChoices
|
||||||
@ -47,30 +51,81 @@ class WebhookFilterSet(BaseFilterSet):
|
|||||||
'http_method', 'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
|
'http_method', 'http_content_type', 'secret', 'ssl_verification', 'ca_file_path',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(payload_url__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomFieldFilterSet(BaseFilterSet):
|
class CustomFieldFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
content_types = ContentTypeFilter()
|
content_types = ContentTypeFilter()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomField
|
model = CustomField
|
||||||
fields = ['id', 'content_types', 'name', 'required', 'filter_logic', 'weight']
|
fields = ['id', 'content_types', 'name', 'required', 'filter_logic', 'weight']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(label__icontains=value) |
|
||||||
|
Q(description__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CustomLinkFilterSet(BaseFilterSet):
|
class CustomLinkFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = CustomLink
|
model = CustomLink
|
||||||
fields = ['id', 'content_type', 'name', 'link_text', 'link_url', 'weight', 'group_name', 'new_window']
|
fields = ['id', 'content_type', 'name', 'link_text', 'link_url', 'weight', 'group_name', 'new_window']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(link_text__icontains=value) |
|
||||||
|
Q(link_url__icontains=value) |
|
||||||
|
Q(group_name__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExportTemplateFilterSet(BaseFilterSet):
|
class ExportTemplateFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = ExportTemplate
|
model = ExportTemplate
|
||||||
fields = ['id', 'content_type', 'name']
|
fields = ['id', 'content_type', 'name']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(description__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ImageAttachmentFilterSet(BaseFilterSet):
|
class ImageAttachmentFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
created = django_filters.DateTimeFilter()
|
created = django_filters.DateTimeFilter()
|
||||||
content_type = ContentTypeFilter()
|
content_type = ContentTypeFilter()
|
||||||
|
|
||||||
@ -78,6 +133,11 @@ class ImageAttachmentFilterSet(BaseFilterSet):
|
|||||||
model = ImageAttachment
|
model = ImageAttachment
|
||||||
fields = ['id', 'content_type_id', 'object_id', 'name']
|
fields = ['id', 'content_type_id', 'object_id', 'name']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(name__icontains=value)
|
||||||
|
|
||||||
|
|
||||||
class JournalEntryFilterSet(ChangeLoggedModelFilterSet):
|
class JournalEntryFilterSet(ChangeLoggedModelFilterSet):
|
||||||
q = django_filters.CharFilter(
|
q = django_filters.CharFilter(
|
||||||
|
@ -99,8 +99,20 @@ class TokenFilterSet(BaseFilterSet):
|
|||||||
model = Token
|
model = Token
|
||||||
fields = ['id', 'key', 'write_enabled']
|
fields = ['id', 'key', 'write_enabled']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(user__username__icontains=value) |
|
||||||
|
Q(description__icontains=value)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ObjectPermissionFilterSet(BaseFilterSet):
|
class ObjectPermissionFilterSet(BaseFilterSet):
|
||||||
|
q = django_filters.CharFilter(
|
||||||
|
method='search',
|
||||||
|
label='Search',
|
||||||
|
)
|
||||||
user_id = django_filters.ModelMultipleChoiceFilter(
|
user_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='users',
|
field_name='users',
|
||||||
queryset=User.objects.all(),
|
queryset=User.objects.all(),
|
||||||
@ -127,3 +139,11 @@ class ObjectPermissionFilterSet(BaseFilterSet):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = ObjectPermission
|
model = ObjectPermission
|
||||||
fields = ['id', 'name', 'enabled', 'object_types']
|
fields = ['id', 'name', 'enabled', 'object_types']
|
||||||
|
|
||||||
|
def search(self, queryset, name, value):
|
||||||
|
if not value.strip():
|
||||||
|
return queryset
|
||||||
|
return queryset.filter(
|
||||||
|
Q(name__icontains=value) |
|
||||||
|
Q(description__icontains=value)
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user