mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
* Initial work on saved filters * Return only enabled/shared filters * Add tests * Clean up filtering of usable SavedFilters
This commit is contained in:
@@ -2,6 +2,6 @@ from .model_forms import *
|
||||
from .filtersets import *
|
||||
from .bulk_edit import *
|
||||
from .bulk_import import *
|
||||
from .customfields import *
|
||||
from .mixins import *
|
||||
from .config import *
|
||||
from .scripts import *
|
||||
|
@@ -1,11 +1,9 @@
|
||||
from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
|
||||
from extras.choices import *
|
||||
from extras.models import *
|
||||
from extras.utils import FeatureQuery
|
||||
from utilities.forms import (
|
||||
add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, ContentTypeChoiceField, StaticSelect,
|
||||
add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, StaticSelect,
|
||||
)
|
||||
|
||||
__all__ = (
|
||||
@@ -14,6 +12,7 @@ __all__ = (
|
||||
'CustomLinkBulkEditForm',
|
||||
'ExportTemplateBulkEditForm',
|
||||
'JournalEntryBulkEditForm',
|
||||
'SavedFilterBulkEditForm',
|
||||
'TagBulkEditForm',
|
||||
'WebhookBulkEditForm',
|
||||
)
|
||||
@@ -96,6 +95,30 @@ class ExportTemplateBulkEditForm(BulkEditForm):
|
||||
nullable_fields = ('description', 'mime_type', 'file_extension')
|
||||
|
||||
|
||||
class SavedFilterBulkEditForm(BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=SavedFilter.objects.all(),
|
||||
widget=forms.MultipleHiddenInput
|
||||
)
|
||||
description = forms.CharField(
|
||||
max_length=200,
|
||||
required=False
|
||||
)
|
||||
weight = forms.IntegerField(
|
||||
required=False
|
||||
)
|
||||
enabled = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=BulkEditNullBooleanSelect()
|
||||
)
|
||||
shared = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=BulkEditNullBooleanSelect()
|
||||
)
|
||||
|
||||
nullable_fields = ('description',)
|
||||
|
||||
|
||||
class WebhookBulkEditForm(BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(
|
||||
queryset=Webhook.objects.all(),
|
||||
|
@@ -12,6 +12,7 @@ __all__ = (
|
||||
'CustomFieldCSVForm',
|
||||
'CustomLinkCSVForm',
|
||||
'ExportTemplateCSVForm',
|
||||
'SavedFilterCSVForm',
|
||||
'TagCSVForm',
|
||||
'WebhookCSVForm',
|
||||
)
|
||||
@@ -81,6 +82,19 @@ class ExportTemplateCSVForm(CSVModelForm):
|
||||
)
|
||||
|
||||
|
||||
class SavedFilterCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
help_text="One or more assigned object types"
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SavedFilter
|
||||
fields = (
|
||||
'name', 'content_types', 'description', 'weight', 'enabled', 'shared', 'parameters',
|
||||
)
|
||||
|
||||
|
||||
class WebhookCSVForm(CSVModelForm):
|
||||
content_types = CSVMultipleContentTypeField(
|
||||
queryset=ContentType.objects.all(),
|
||||
|
@@ -15,6 +15,7 @@ from utilities.forms import (
|
||||
StaticSelect, TagFilterField,
|
||||
)
|
||||
from virtualization.models import Cluster, ClusterGroup, ClusterType
|
||||
from .mixins import SavedFiltersMixin
|
||||
|
||||
__all__ = (
|
||||
'ConfigContextFilterForm',
|
||||
@@ -25,14 +26,15 @@ __all__ = (
|
||||
'JournalEntryFilterForm',
|
||||
'LocalConfigContextFilterForm',
|
||||
'ObjectChangeFilterForm',
|
||||
'SavedFilterFilterForm',
|
||||
'TagFilterForm',
|
||||
'WebhookFilterForm',
|
||||
)
|
||||
|
||||
|
||||
class CustomFieldFilterForm(FilterForm):
|
||||
class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('type', 'content_type_id', 'group_name', 'weight', 'required', 'ui_visibility')),
|
||||
)
|
||||
content_type_id = ContentTypeMultipleChoiceField(
|
||||
@@ -66,9 +68,9 @@ class CustomFieldFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class JobResultFilterForm(FilterForm):
|
||||
class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('obj_type', 'status')),
|
||||
('Creation', ('created__before', 'created__after', 'completed__before', 'completed__after',
|
||||
'scheduled_time__before', 'scheduled_time__after', 'user')),
|
||||
@@ -118,9 +120,9 @@ class JobResultFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class CustomLinkFilterForm(FilterForm):
|
||||
class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('content_types', 'enabled', 'new_window', 'weight')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
@@ -145,9 +147,9 @@ class CustomLinkFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class ExportTemplateFilterForm(FilterForm):
|
||||
class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('content_types', 'mime_type', 'file_extension', 'as_attachment')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
@@ -170,9 +172,36 @@ class ExportTemplateFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class WebhookFilterForm(FilterForm):
|
||||
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('content_types', 'enabled', 'shared', 'weight')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
limit_choices_to=FeatureQuery('export_templates'),
|
||||
required=False
|
||||
)
|
||||
enabled = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=StaticSelect(
|
||||
choices=BOOLEAN_WITH_BLANK_CHOICES
|
||||
)
|
||||
)
|
||||
shared = forms.NullBooleanField(
|
||||
required=False,
|
||||
widget=StaticSelect(
|
||||
choices=BOOLEAN_WITH_BLANK_CHOICES
|
||||
)
|
||||
)
|
||||
weight = forms.IntegerField(
|
||||
required=False
|
||||
)
|
||||
|
||||
|
||||
class WebhookFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
('Attributes', ('content_type_id', 'http_method', 'enabled')),
|
||||
('Events', ('type_create', 'type_update', 'type_delete')),
|
||||
)
|
||||
@@ -213,7 +242,7 @@ class WebhookFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class TagFilterForm(FilterForm):
|
||||
class TagFilterForm(SavedFiltersMixin, FilterForm):
|
||||
model = Tag
|
||||
content_type_id = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.filter(FeatureQuery('tags').get_query()),
|
||||
@@ -222,9 +251,9 @@ class TagFilterForm(FilterForm):
|
||||
)
|
||||
|
||||
|
||||
class ConfigContextFilterForm(FilterForm):
|
||||
class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag_id')),
|
||||
(None, ('q', 'filter', 'tag_id')),
|
||||
('Location', ('region_id', 'site_group_id', 'site_id', 'location_id')),
|
||||
('Device', ('device_type_id', 'platform_id', 'role_id')),
|
||||
('Cluster', ('cluster_type_id', 'cluster_group_id', 'cluster_id')),
|
||||
@@ -311,7 +340,7 @@ class LocalConfigContextFilterForm(forms.Form):
|
||||
class JournalEntryFilterForm(NetBoxModelFilterSetForm):
|
||||
model = JournalEntry
|
||||
fieldsets = (
|
||||
(None, ('q', 'tag')),
|
||||
(None, ('q', 'filter', 'tag')),
|
||||
('Creation', ('created_before', 'created_after', 'created_by_id')),
|
||||
('Attributes', ('assigned_object_type_id', 'kind'))
|
||||
)
|
||||
@@ -349,10 +378,10 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
|
||||
tag = TagFilterField(model)
|
||||
|
||||
|
||||
class ObjectChangeFilterForm(FilterForm):
|
||||
class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
|
||||
model = ObjectChange
|
||||
fieldsets = (
|
||||
(None, ('q',)),
|
||||
(None, ('q', 'filter')),
|
||||
('Time', ('time_before', 'time_after')),
|
||||
('Attributes', ('action', 'user_id', 'changed_object_type_id')),
|
||||
)
|
||||
|
@@ -1,10 +1,13 @@
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django import forms
|
||||
|
||||
from extras.models import *
|
||||
from extras.choices import CustomFieldVisibilityChoices
|
||||
from utilities.forms.fields import DynamicModelMultipleChoiceField
|
||||
|
||||
__all__ = (
|
||||
'CustomFieldsMixin',
|
||||
'SavedFiltersMixin',
|
||||
)
|
||||
|
||||
|
||||
@@ -57,3 +60,14 @@ class CustomFieldsMixin:
|
||||
if customfield.group_name not in self.custom_field_groups:
|
||||
self.custom_field_groups[customfield.group_name] = []
|
||||
self.custom_field_groups[customfield.group_name].append(field_name)
|
||||
|
||||
|
||||
class SavedFiltersMixin(forms.Form):
|
||||
filter = DynamicModelMultipleChoiceField(
|
||||
queryset=SavedFilter.objects.all(),
|
||||
required=False,
|
||||
label='Saved Filter',
|
||||
query_params={
|
||||
'usable': True,
|
||||
}
|
||||
)
|
@@ -1,5 +1,6 @@
|
||||
from django import forms
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.http import QueryDict
|
||||
|
||||
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
|
||||
from extras.choices import *
|
||||
@@ -20,6 +21,7 @@ __all__ = (
|
||||
'ExportTemplateForm',
|
||||
'ImageAttachmentForm',
|
||||
'JournalEntryForm',
|
||||
'SavedFilterForm',
|
||||
'TagForm',
|
||||
'WebhookForm',
|
||||
)
|
||||
@@ -108,6 +110,34 @@ class ExportTemplateForm(BootstrapMixin, forms.ModelForm):
|
||||
}
|
||||
|
||||
|
||||
class SavedFilterForm(BootstrapMixin, forms.ModelForm):
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all()
|
||||
)
|
||||
|
||||
fieldsets = (
|
||||
('Saved Filter', ('name', 'content_types', 'description', 'weight', 'enabled', 'shared')),
|
||||
('Parameters', ('parameters',)),
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = SavedFilter
|
||||
exclude = ('user',)
|
||||
widgets = {
|
||||
'parameters': forms.Textarea(attrs={'class': 'font-monospace'}),
|
||||
}
|
||||
|
||||
def __init__(self, *args, initial=None, **kwargs):
|
||||
|
||||
# Convert any parameters delivered via initial data to a dictionary
|
||||
if initial and 'parameters' in initial:
|
||||
if type(initial['parameters']) is str:
|
||||
# TODO: Make a utility function for this
|
||||
initial['parameters'] = dict(QueryDict(initial['parameters']).lists())
|
||||
|
||||
super().__init__(*args, initial=initial, **kwargs)
|
||||
|
||||
|
||||
class WebhookForm(BootstrapMixin, forms.ModelForm):
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all(),
|
||||
|
Reference in New Issue
Block a user