Closes #14591: Saved table configurations (#19101)

* Add SavedTableConfig

* Update table configuration logic to support TableConfigs

* Update table config link when updating table

* Correct docstring

* Misc cleanup

* Use multi-select widgets for column selection

* Return null config params for tables with no model

* Fix auto-selection of selected columns

* Update migration

* Clean up template

* Enforce enabled/shared flags

* Search/filter by table name

* Misc cleanup

* Fix population of selected columns

* Ordering field should not be required

* Enable cloning for TableConfig

* Misc cleanup

* Add model documentation for TableConfig

* Drop slug field from TableConfig

* Improve TableConfig validation

* Remove add button from TableConfig list view

* Fix ordering validation to account for leading hyphens
This commit is contained in:
Jeremy Stretch
2025-04-10 16:48:02 -04:00
committed by GitHub
parent f8f2ad1d14
commit bb5057c063
32 changed files with 856 additions and 102 deletions

View File

@@ -32,6 +32,7 @@ __all__ = (
'ObjectTypeFilterSet',
'SavedFilterFilterSet',
'ScriptFilterSet',
'TableConfigFilterSet',
'TagFilterSet',
'TaggedItemFilterSet',
'WebhookFilterSet',
@@ -326,6 +327,59 @@ class SavedFilterFilterSet(ChangeLoggedModelFilterSet):
return queryset.filter(Q(enabled=False) | Q(Q(shared=False) & ~Q(user=user)))
class TableConfigFilterSet(ChangeLoggedModelFilterSet):
q = django_filters.CharFilter(
method='search',
label=_('Search'),
)
object_type_id = django_filters.ModelMultipleChoiceFilter(
queryset=ObjectType.objects.all(),
field_name='object_type'
)
object_type = ContentTypeFilter(
field_name='object_type'
)
user_id = django_filters.ModelMultipleChoiceFilter(
queryset=User.objects.all(),
label=_('User (ID)'),
)
user = django_filters.ModelMultipleChoiceFilter(
field_name='user__username',
queryset=User.objects.all(),
to_field_name='username',
label=_('User (name)'),
)
usable = django_filters.BooleanFilter(
method='_usable'
)
class Meta:
model = TableConfig
fields = ('id', 'name', 'description', 'table', 'enabled', 'shared', 'weight')
def search(self, queryset, name, value):
if not value.strip():
return queryset
return queryset.filter(
Q(name__icontains=value) |
Q(description__icontains=value) |
Q(table__icontains=value)
)
def _usable(self, queryset, name, value):
"""
Return only TableConfigs that are both enabled and are shared (or belong to the current user).
"""
user = self.request.user if self.request else None
if not user or user.is_anonymous:
if value:
return queryset.filter(enabled=True, shared=True)
return queryset.filter(Q(enabled=False) | Q(shared=False))
if value:
return queryset.filter(enabled=True).filter(Q(shared=True) | Q(user=user))
return queryset.filter(Q(enabled=False) | Q(Q(shared=False) & ~Q(user=user)))
class BookmarkFilterSet(BaseFilterSet):
created = django_filters.DateTimeFilter()
object_type_id = MultiValueNumberFilter()