mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
#9623: Add slug field to SavedFilter
This commit is contained in:
@@ -64,7 +64,7 @@ class NestedSavedFilterSerializer(WritableNestedSerializer):
|
||||
|
||||
class Meta:
|
||||
model = models.SavedFilter
|
||||
fields = ['id', 'url', 'display', 'name']
|
||||
fields = ['id', 'url', 'display', 'name', 'slug']
|
||||
|
||||
|
||||
class NestedImageAttachmentSerializer(WritableNestedSerializer):
|
||||
|
@@ -164,8 +164,8 @@ class SavedFilterSerializer(ValidatedModelSerializer):
|
||||
class Meta:
|
||||
model = SavedFilter
|
||||
fields = [
|
||||
'id', 'url', 'display', 'content_types', 'name', 'description', 'user', 'weight',
|
||||
'enabled', 'shared', 'parameters', 'created', 'last_updated',
|
||||
'id', 'url', 'display', 'content_types', 'name', 'slug', 'description', 'user', 'weight', 'enabled',
|
||||
'shared', 'parameters', 'created', 'last_updated',
|
||||
]
|
||||
|
||||
|
||||
|
@@ -165,7 +165,7 @@ class SavedFilterFilterSet(BaseFilterSet):
|
||||
|
||||
class Meta:
|
||||
model = SavedFilter
|
||||
fields = ['id', 'content_types', 'name', 'description', 'enabled', 'shared', 'weight']
|
||||
fields = ['id', 'content_types', 'name', 'slug', 'description', 'enabled', 'shared', 'weight']
|
||||
|
||||
def search(self, queryset, name, value):
|
||||
if not value.strip():
|
||||
|
@@ -92,7 +92,7 @@ class SavedFilterCSVForm(CSVModelForm):
|
||||
class Meta:
|
||||
model = SavedFilter
|
||||
fields = (
|
||||
'name', 'content_types', 'description', 'weight', 'enabled', 'shared', 'parameters',
|
||||
'name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared', 'parameters',
|
||||
)
|
||||
|
||||
|
||||
|
@@ -34,7 +34,7 @@ __all__ = (
|
||||
|
||||
class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('type', 'content_type_id', 'group_name', 'weight', 'required', 'ui_visibility')),
|
||||
)
|
||||
content_type_id = ContentTypeMultipleChoiceField(
|
||||
@@ -70,7 +70,7 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('obj_type', 'status')),
|
||||
('Creation', ('created__before', 'created__after', 'completed__before', 'completed__after',
|
||||
'scheduled_time__before', 'scheduled_time__after', 'user')),
|
||||
@@ -122,7 +122,7 @@ class JobResultFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('content_types', 'enabled', 'new_window', 'weight')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
@@ -149,7 +149,7 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('content_types', 'mime_type', 'file_extension', 'as_attachment')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
@@ -174,7 +174,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('content_types', 'enabled', 'shared', 'weight')),
|
||||
)
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
@@ -201,7 +201,7 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class WebhookFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Attributes', ('content_type_id', 'http_method', 'enabled')),
|
||||
('Events', ('type_create', 'type_update', 'type_delete')),
|
||||
)
|
||||
@@ -253,7 +253,7 @@ class TagFilterForm(SavedFiltersMixin, FilterForm):
|
||||
|
||||
class ConfigContextFilterForm(SavedFiltersMixin, FilterForm):
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter', 'tag_id')),
|
||||
(None, ('q', 'filter_id', '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')),
|
||||
@@ -340,7 +340,7 @@ class LocalConfigContextFilterForm(forms.Form):
|
||||
class JournalEntryFilterForm(NetBoxModelFilterSetForm):
|
||||
model = JournalEntry
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter', 'tag')),
|
||||
(None, ('q', 'filter_id', 'tag')),
|
||||
('Creation', ('created_before', 'created_after', 'created_by_id')),
|
||||
('Attributes', ('assigned_object_type_id', 'kind'))
|
||||
)
|
||||
@@ -381,7 +381,7 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
|
||||
class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
|
||||
model = ObjectChange
|
||||
fieldsets = (
|
||||
(None, ('q', 'filter')),
|
||||
(None, ('q', 'filter_id')),
|
||||
('Time', ('time_before', 'time_after')),
|
||||
('Attributes', ('action', 'user_id', 'changed_object_type_id')),
|
||||
)
|
||||
|
@@ -64,7 +64,7 @@ class CustomFieldsMixin:
|
||||
|
||||
|
||||
class SavedFiltersMixin(forms.Form):
|
||||
filter = DynamicModelMultipleChoiceField(
|
||||
filter_id = DynamicModelMultipleChoiceField(
|
||||
queryset=SavedFilter.objects.all(),
|
||||
required=False,
|
||||
label=_('Saved Filter'),
|
||||
|
@@ -112,12 +112,13 @@ class ExportTemplateForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class SavedFilterForm(BootstrapMixin, forms.ModelForm):
|
||||
slug = SlugField()
|
||||
content_types = ContentTypeMultipleChoiceField(
|
||||
queryset=ContentType.objects.all()
|
||||
)
|
||||
|
||||
fieldsets = (
|
||||
('Saved Filter', ('name', 'content_types', 'description', 'weight', 'enabled', 'shared')),
|
||||
('Saved Filter', ('name', 'slug', 'content_types', 'description', 'weight', 'enabled', 'shared')),
|
||||
('Parameters', ('parameters',)),
|
||||
)
|
||||
|
||||
|
@@ -1,8 +1,6 @@
|
||||
# Generated by Django 4.1.1 on 2022-10-27 18:18
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
@@ -21,6 +19,7 @@ class Migration(migrations.Migration):
|
||||
('created', models.DateTimeField(auto_now_add=True, null=True)),
|
||||
('last_updated', models.DateTimeField(auto_now=True, null=True)),
|
||||
('name', models.CharField(max_length=100, unique=True)),
|
||||
('slug', models.SlugField(max_length=100, unique=True)),
|
||||
('description', models.CharField(blank=True, max_length=200)),
|
||||
('weight', models.PositiveSmallIntegerField(default=100)),
|
||||
('enabled', models.BooleanField(default=True)),
|
||||
|
@@ -365,6 +365,10 @@ class SavedFilter(CloningMixin, ExportTemplatesMixin, WebhooksMixin, ChangeLogge
|
||||
max_length=100,
|
||||
unique=True
|
||||
)
|
||||
slug = models.SlugField(
|
||||
max_length=100,
|
||||
unique=True
|
||||
)
|
||||
description = models.CharField(
|
||||
max_length=200,
|
||||
blank=True
|
||||
|
@@ -100,7 +100,7 @@ class SavedFilterTable(NetBoxTable):
|
||||
class Meta(NetBoxTable.Meta):
|
||||
model = SavedFilter
|
||||
fields = (
|
||||
'pk', 'id', 'name', 'content_types', 'description', 'user', 'weight', 'enabled', 'shared',
|
||||
'pk', 'id', 'name', 'slug', 'content_types', 'description', 'user', 'weight', 'enabled', 'shared',
|
||||
'created', 'last_updated',
|
||||
)
|
||||
default_columns = (
|
||||
|
@@ -192,11 +192,12 @@ class CustomLinkTest(APIViewTestCases.APIViewTestCase):
|
||||
|
||||
class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
model = SavedFilter
|
||||
brief_fields = ['display', 'id', 'name', 'url']
|
||||
brief_fields = ['display', 'id', 'name', 'slug', 'url']
|
||||
create_data = [
|
||||
{
|
||||
'content_types': ['dcim.site'],
|
||||
'name': 'Saved Filter 4',
|
||||
'slug': 'saved-filter-4',
|
||||
'weight': 100,
|
||||
'enabled': True,
|
||||
'shared': True,
|
||||
@@ -205,6 +206,7 @@ class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'content_types': ['dcim.site'],
|
||||
'name': 'Saved Filter 5',
|
||||
'slug': 'saved-filter-5',
|
||||
'weight': 200,
|
||||
'enabled': True,
|
||||
'shared': True,
|
||||
@@ -213,6 +215,7 @@ class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
{
|
||||
'content_types': ['dcim.site'],
|
||||
'name': 'Saved Filter 6',
|
||||
'slug': 'saved-filter-6',
|
||||
'weight': 300,
|
||||
'enabled': True,
|
||||
'shared': True,
|
||||
@@ -232,6 +235,7 @@ class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
saved_filters = (
|
||||
SavedFilter(
|
||||
name='Saved Filter 1',
|
||||
slug='saved-filter-1',
|
||||
weight=100,
|
||||
enabled=True,
|
||||
shared=True,
|
||||
@@ -239,6 +243,7 @@ class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 2',
|
||||
slug='saved-filter-2',
|
||||
weight=200,
|
||||
enabled=True,
|
||||
shared=True,
|
||||
@@ -246,6 +251,7 @@ class SavedFilterTest(APIViewTestCases.APIViewTestCase):
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 3',
|
||||
slug='saved-filter-3',
|
||||
weight=300,
|
||||
enabled=True,
|
||||
shared=True,
|
||||
|
@@ -240,6 +240,7 @@ class SavedFilterTestCase(TestCase, BaseFilterSetTests):
|
||||
saved_filters = (
|
||||
SavedFilter(
|
||||
name='Saved Filter 1',
|
||||
slug='saved-filter-1',
|
||||
user=users[0],
|
||||
weight=100,
|
||||
enabled=True,
|
||||
@@ -248,6 +249,7 @@ class SavedFilterTestCase(TestCase, BaseFilterSetTests):
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 2',
|
||||
slug='saved-filter-2',
|
||||
user=users[1],
|
||||
weight=200,
|
||||
enabled=True,
|
||||
@@ -256,6 +258,7 @@ class SavedFilterTestCase(TestCase, BaseFilterSetTests):
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 3',
|
||||
slug='saved-filter-3',
|
||||
user=users[2],
|
||||
weight=300,
|
||||
enabled=False,
|
||||
@@ -271,6 +274,10 @@ class SavedFilterTestCase(TestCase, BaseFilterSetTests):
|
||||
params = {'name': ['Saved Filter 1', 'Saved Filter 2']}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2)
|
||||
|
||||
def test_slug(self):
|
||||
params = {'slug': ['saved-filter-1', 'saved-filter-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)
|
||||
|
@@ -122,9 +122,27 @@ class SavedFilterTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
User.objects.bulk_create(users)
|
||||
|
||||
saved_filters = (
|
||||
SavedFilter(name='Saved Filter 1', user=users[0], weight=100, parameters={'status': ['active']}),
|
||||
SavedFilter(name='Saved Filter 2', user=users[1], weight=200, parameters={'status': ['planned']}),
|
||||
SavedFilter(name='Saved Filter 3', user=users[2], weight=300, parameters={'status': ['retired']}),
|
||||
SavedFilter(
|
||||
name='Saved Filter 1',
|
||||
slug='saved-filter-1',
|
||||
user=users[0],
|
||||
weight=100,
|
||||
parameters={'status': ['active']}
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 2',
|
||||
slug='saved-filter-2',
|
||||
user=users[1],
|
||||
weight=200,
|
||||
parameters={'status': ['planned']}
|
||||
),
|
||||
SavedFilter(
|
||||
name='Saved Filter 3',
|
||||
slug='saved-filter-3',
|
||||
user=users[2],
|
||||
weight=300,
|
||||
parameters={'status': ['retired']}
|
||||
),
|
||||
)
|
||||
SavedFilter.objects.bulk_create(saved_filters)
|
||||
for i, savedfilter in enumerate(saved_filters):
|
||||
@@ -132,6 +150,7 @@ class SavedFilterTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
|
||||
cls.form_data = {
|
||||
'name': 'Saved Filter X',
|
||||
'slug': 'saved-filter-x',
|
||||
'content_types': [site_ct.pk],
|
||||
'description': 'Foo',
|
||||
'weight': 1000,
|
||||
@@ -141,10 +160,10 @@ class SavedFilterTestCase(ViewTestCases.PrimaryObjectViewTestCase):
|
||||
}
|
||||
|
||||
cls.csv_data = (
|
||||
'name,content_types,weight,enabled,shared,parameters',
|
||||
'Saved Filter 4,dcim.device,400,True,True,{"foo": "a"}',
|
||||
'Saved Filter 5,dcim.device,500,True,True,{"foo": "b"}',
|
||||
'Saved Filter 6,dcim.device,600,True,True,{"foo": "c"}',
|
||||
'name,slug,content_types,weight,enabled,shared,parameters',
|
||||
'Saved Filter 4,saved-filter-4,dcim.device,400,True,True,{"foo": "a"}',
|
||||
'Saved Filter 5,saved-filter-5,dcim.device,500,True,True,{"foo": "b"}',
|
||||
'Saved Filter 6,saved-filter-6,dcim.device,600,True,True,{"foo": "c"}',
|
||||
)
|
||||
|
||||
cls.csv_update_data = (
|
||||
|
Reference in New Issue
Block a user