mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #6954: Remember users' table ordering preferences
This commit is contained in:
@ -4,9 +4,10 @@ The `users.UserConfig` model holds individual preferences for each user in the f
|
|||||||
|
|
||||||
## Available Preferences
|
## Available Preferences
|
||||||
|
|
||||||
| Name | Description |
|
| Name | Description |
|
||||||
|-------------------------|-------------|
|
|--------------------------|---------------------------------------------------------------|
|
||||||
| data_format | Preferred format when rendering raw data (JSON or YAML) |
|
| data_format | Preferred format when rendering raw data (JSON or YAML) |
|
||||||
| pagination.per_page | The number of items to display per page of a paginated table |
|
| pagination.per_page | The number of items to display per page of a paginated table |
|
||||||
| tables.${table}.columns | The ordered list of columns to display when viewing the table |
|
| tables.${table}.columns | The ordered list of columns to display when viewing the table |
|
||||||
| ui.colormode | Light or dark mode in the user interface |
|
| tables.${table}.ordering | A list of column names by which the table should be ordered |
|
||||||
|
| ui.colormode | Light or dark mode in the user interface |
|
||||||
|
@ -56,6 +56,7 @@ Inventory item templates can be arranged hierarchically within a device type, an
|
|||||||
|
|
||||||
### Enhancements
|
### Enhancements
|
||||||
|
|
||||||
|
* [#6954](https://github.com/netbox-community/netbox/issues/6954) - Remember users' table ordering preferences
|
||||||
* [#7650](https://github.com/netbox-community/netbox/issues/7650) - Add support for local account password validation
|
* [#7650](https://github.com/netbox-community/netbox/issues/7650) - Add support for local account password validation
|
||||||
* [#7679](https://github.com/netbox-community/netbox/issues/7679) - Add actions menu to all object tables
|
* [#7679](https://github.com/netbox-community/netbox/issues/7679) - Add actions menu to all object tables
|
||||||
* [#7681](https://github.com/netbox-community/netbox/issues/7681) - Add `service_id` field for provider networks
|
* [#7681](https://github.com/netbox-community/netbox/issues/7681) - Add `service_id` field for provider networks
|
||||||
|
@ -5,7 +5,7 @@ from django.shortcuts import get_object_or_404, redirect, render
|
|||||||
|
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
from .choices import CircuitTerminationSideChoices
|
from .choices import CircuitTerminationSideChoices
|
||||||
@ -35,7 +35,7 @@ class ProviderView(generic.ObjectView):
|
|||||||
'type', 'tenant', 'terminations__site'
|
'type', 'tenant', 'terminations__site'
|
||||||
)
|
)
|
||||||
circuits_table = tables.CircuitTable(circuits, exclude=('provider',))
|
circuits_table = tables.CircuitTable(circuits, exclude=('provider',))
|
||||||
paginate_table(circuits_table, request)
|
configure_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'circuits_table': circuits_table,
|
'circuits_table': circuits_table,
|
||||||
@ -96,7 +96,7 @@ class ProviderNetworkView(generic.ObjectView):
|
|||||||
'type', 'tenant', 'terminations__site'
|
'type', 'tenant', 'terminations__site'
|
||||||
)
|
)
|
||||||
circuits_table = tables.CircuitTable(circuits)
|
circuits_table = tables.CircuitTable(circuits)
|
||||||
paginate_table(circuits_table, request)
|
configure_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'circuits_table': circuits_table,
|
'circuits_table': circuits_table,
|
||||||
@ -150,7 +150,7 @@ class CircuitTypeView(generic.ObjectView):
|
|||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
circuits = Circuit.objects.restrict(request.user, 'view').filter(type=instance)
|
circuits = Circuit.objects.restrict(request.user, 'view').filter(type=instance)
|
||||||
circuits_table = tables.CircuitTable(circuits, exclude=('type',))
|
circuits_table = tables.CircuitTable(circuits, exclude=('type',))
|
||||||
paginate_table(circuits_table, request)
|
configure_table(circuits_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'circuits_table': circuits_table,
|
'circuits_table': circuits_table,
|
||||||
|
@ -20,7 +20,7 @@ from netbox.views import generic
|
|||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
from utilities.paginator import EnhancedPaginator, get_paginate_count
|
||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
|
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
|
||||||
from virtualization.models import VirtualMachine
|
from virtualization.models import VirtualMachine
|
||||||
@ -165,7 +165,7 @@ class RegionView(generic.ObjectView):
|
|||||||
region=instance
|
region=instance
|
||||||
)
|
)
|
||||||
sites_table = tables.SiteTable(sites, exclude=('region',))
|
sites_table = tables.SiteTable(sites, exclude=('region',))
|
||||||
paginate_table(sites_table, request)
|
configure_table(sites_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'child_regions_table': child_regions_table,
|
'child_regions_table': child_regions_table,
|
||||||
@ -250,7 +250,7 @@ class SiteGroupView(generic.ObjectView):
|
|||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
sites_table = tables.SiteTable(sites, exclude=('group',))
|
sites_table = tables.SiteTable(sites, exclude=('group',))
|
||||||
paginate_table(sites_table, request)
|
configure_table(sites_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'child_groups_table': child_groups_table,
|
'child_groups_table': child_groups_table,
|
||||||
@ -422,7 +422,7 @@ class LocationView(generic.ObjectView):
|
|||||||
cumulative=True
|
cumulative=True
|
||||||
).filter(pk__in=location_ids).exclude(pk=instance.pk)
|
).filter(pk__in=location_ids).exclude(pk=instance.pk)
|
||||||
child_locations_table = tables.LocationTable(child_locations)
|
child_locations_table = tables.LocationTable(child_locations)
|
||||||
paginate_table(child_locations_table, request)
|
configure_table(child_locations_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'rack_count': rack_count,
|
'rack_count': rack_count,
|
||||||
@ -493,7 +493,7 @@ class RackRoleView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
racks_table = tables.RackTable(racks, exclude=('role', 'get_utilization', 'get_power_utilization'))
|
racks_table = tables.RackTable(racks, exclude=('role', 'get_utilization', 'get_power_utilization'))
|
||||||
paginate_table(racks_table, request)
|
configure_table(racks_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'racks_table': racks_table,
|
'racks_table': racks_table,
|
||||||
@ -743,7 +743,7 @@ class ManufacturerView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
devicetypes_table = tables.DeviceTypeTable(devicetypes, exclude=('manufacturer',))
|
devicetypes_table = tables.DeviceTypeTable(devicetypes, exclude=('manufacturer',))
|
||||||
paginate_table(devicetypes_table, request)
|
configure_table(devicetypes_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'devicetypes_table': devicetypes_table,
|
'devicetypes_table': devicetypes_table,
|
||||||
@ -1439,7 +1439,7 @@ class DeviceRoleView(generic.ObjectView):
|
|||||||
device_role=instance
|
device_role=instance
|
||||||
)
|
)
|
||||||
devices_table = tables.DeviceTable(devices, exclude=('device_role',))
|
devices_table = tables.DeviceTable(devices, exclude=('device_role',))
|
||||||
paginate_table(devices_table, request)
|
configure_table(devices_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'devices_table': devices_table,
|
'devices_table': devices_table,
|
||||||
@ -1503,7 +1503,7 @@ class PlatformView(generic.ObjectView):
|
|||||||
platform=instance
|
platform=instance
|
||||||
)
|
)
|
||||||
devices_table = tables.DeviceTable(devices, exclude=('platform',))
|
devices_table = tables.DeviceTable(devices, exclude=('platform',))
|
||||||
paginate_table(devices_table, request)
|
configure_table(devices_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'devices_table': devices_table,
|
'devices_table': devices_table,
|
||||||
|
@ -11,7 +11,7 @@ from rq import Worker
|
|||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.forms import ConfirmationForm
|
from utilities.forms import ConfirmationForm
|
||||||
from utilities.htmx import is_htmx
|
from utilities.htmx import is_htmx
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import copy_safe_request, count_related, normalize_querydict, shallow_compare_dict
|
from utilities.utils import copy_safe_request, count_related, normalize_querydict, shallow_compare_dict
|
||||||
from utilities.views import ContentTypePermissionRequiredMixin
|
from utilities.views import ContentTypePermissionRequiredMixin
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
@ -215,7 +215,7 @@ class TagView(generic.ObjectView):
|
|||||||
data=tagged_items,
|
data=tagged_items,
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
paginate_table(taggeditem_table, request)
|
configure_table(taggeditem_table, request)
|
||||||
|
|
||||||
object_types = [
|
object_types = [
|
||||||
{
|
{
|
||||||
@ -451,7 +451,7 @@ class ObjectChangeLogView(View):
|
|||||||
data=objectchanges,
|
data=objectchanges,
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
paginate_table(objectchanges_table, request)
|
configure_table(objectchanges_table, request)
|
||||||
|
|
||||||
# Default to using "<app>/<model>.html" as the template, if it exists. Otherwise,
|
# Default to using "<app>/<model>.html" as the template, if it exists. Otherwise,
|
||||||
# fall back to using base.html.
|
# fall back to using base.html.
|
||||||
@ -571,7 +571,7 @@ class ObjectJournalView(View):
|
|||||||
assigned_object_id=obj.pk
|
assigned_object_id=obj.pk
|
||||||
)
|
)
|
||||||
journalentry_table = tables.ObjectJournalTable(journalentries)
|
journalentry_table = tables.ObjectJournalTable(journalentries)
|
||||||
paginate_table(journalentry_table, request)
|
configure_table(journalentry_table, request)
|
||||||
|
|
||||||
if request.user.has_perm('extras.add_journalentry'):
|
if request.user.has_perm('extras.add_journalentry'):
|
||||||
form = forms.JournalEntryForm(
|
form = forms.JournalEntryForm(
|
||||||
|
@ -8,7 +8,7 @@ from dcim.filtersets import InterfaceFilterSet
|
|||||||
from dcim.models import Interface, Site
|
from dcim.models import Interface, Site
|
||||||
from dcim.tables import SiteTable
|
from dcim.tables import SiteTable
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from virtualization.filtersets import VMInterfaceFilterSet
|
from virtualization.filtersets import VMInterfaceFilterSet
|
||||||
from virtualization.models import VMInterface
|
from virtualization.models import VMInterface
|
||||||
@ -161,7 +161,7 @@ class RIRView(generic.ObjectView):
|
|||||||
rir=instance
|
rir=instance
|
||||||
)
|
)
|
||||||
aggregates_table = tables.AggregateTable(aggregates, exclude=('rir', 'utilization'))
|
aggregates_table = tables.AggregateTable(aggregates, exclude=('rir', 'utilization'))
|
||||||
paginate_table(aggregates_table, request)
|
configure_table(aggregates_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'aggregates_table': aggregates_table,
|
'aggregates_table': aggregates_table,
|
||||||
@ -219,7 +219,7 @@ class ASNView(generic.ObjectView):
|
|||||||
def get_extra_context(self, request, instance):
|
def get_extra_context(self, request, instance):
|
||||||
sites = instance.sites.restrict(request.user, 'view')
|
sites = instance.sites.restrict(request.user, 'view')
|
||||||
sites_table = SiteTable(sites)
|
sites_table = SiteTable(sites)
|
||||||
paginate_table(sites_table, request)
|
configure_table(sites_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'sites_table': sites_table,
|
'sites_table': sites_table,
|
||||||
@ -356,7 +356,7 @@ class RoleView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
|
|
||||||
prefixes_table = tables.PrefixTable(prefixes, exclude=('role', 'utilization'))
|
prefixes_table = tables.PrefixTable(prefixes, exclude=('role', 'utilization'))
|
||||||
paginate_table(prefixes_table, request)
|
configure_table(prefixes_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'prefixes_table': prefixes_table,
|
'prefixes_table': prefixes_table,
|
||||||
@ -664,7 +664,7 @@ class IPAddressView(generic.ObjectView):
|
|||||||
vrf=instance.vrf, address__net_contained_or_equal=str(instance.address)
|
vrf=instance.vrf, address__net_contained_or_equal=str(instance.address)
|
||||||
)
|
)
|
||||||
related_ips_table = tables.IPAddressTable(related_ips, orderable=False)
|
related_ips_table = tables.IPAddressTable(related_ips, orderable=False)
|
||||||
paginate_table(related_ips_table, request)
|
configure_table(related_ips_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'parent_prefixes_table': parent_prefixes_table,
|
'parent_prefixes_table': parent_prefixes_table,
|
||||||
@ -800,7 +800,7 @@ class VLANGroupView(generic.ObjectView):
|
|||||||
vlans_table = tables.VLANTable(vlans, exclude=('site', 'group', 'prefixes'))
|
vlans_table = tables.VLANTable(vlans, exclude=('site', 'group', 'prefixes'))
|
||||||
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
if request.user.has_perm('ipam.change_vlan') or request.user.has_perm('ipam.delete_vlan'):
|
||||||
vlans_table.columns.show('pk')
|
vlans_table.columns.show('pk')
|
||||||
paginate_table(vlans_table, request)
|
configure_table(vlans_table, request)
|
||||||
|
|
||||||
# Compile permissions list for rendering the object table
|
# Compile permissions list for rendering the object table
|
||||||
permissions = {
|
permissions = {
|
||||||
|
@ -15,7 +15,6 @@ from django.utils.safestring import mark_safe
|
|||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
from django_tables2.export import TableExport
|
from django_tables2.export import TableExport
|
||||||
|
|
||||||
from dcim.forms.object_create import ComponentCreateForm
|
|
||||||
from extras.models import ExportTemplate
|
from extras.models import ExportTemplate
|
||||||
from extras.signals import clear_webhooks
|
from extras.signals import clear_webhooks
|
||||||
from utilities.error_handlers import handle_protectederror
|
from utilities.error_handlers import handle_protectederror
|
||||||
@ -23,7 +22,7 @@ from utilities.exceptions import AbortTransaction, PermissionsViolation
|
|||||||
from utilities.forms import ConfirmationForm, ImportForm, restrict_form_fields
|
from utilities.forms import ConfirmationForm, ImportForm, restrict_form_fields
|
||||||
from utilities.htmx import is_htmx
|
from utilities.htmx import is_htmx
|
||||||
from utilities.permissions import get_permission_for_model
|
from utilities.permissions import get_permission_for_model
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import normalize_querydict, prepare_cloned_fields
|
from utilities.utils import normalize_querydict, prepare_cloned_fields
|
||||||
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
|
from utilities.views import GetReturnURLMixin, ObjectPermissionRequiredMixin
|
||||||
|
|
||||||
@ -135,7 +134,7 @@ class ObjectChildrenView(ObjectView):
|
|||||||
# Determine whether to display bulk action checkboxes
|
# Determine whether to display bulk action checkboxes
|
||||||
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
if 'pk' in table.base_columns and (permissions['change'] or permissions['delete']):
|
||||||
table.columns.show('pk')
|
table.columns.show('pk')
|
||||||
paginate_table(table, request)
|
configure_table(table, request)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# If this is an HTMX request, return only the rendered table HTML
|
||||||
if is_htmx(request):
|
if is_htmx(request):
|
||||||
@ -284,7 +283,7 @@ class ObjectListView(ObjectPermissionRequiredMixin, View):
|
|||||||
|
|
||||||
# Render the objects table
|
# Render the objects table
|
||||||
table = self.get_table(request, permissions)
|
table = self.get_table(request, permissions)
|
||||||
paginate_table(table, request)
|
configure_table(table, request)
|
||||||
|
|
||||||
# If this is an HTMX request, return only the rendered table HTML
|
# If this is an HTMX request, return only the rendered table HTML
|
||||||
if is_htmx(request):
|
if is_htmx(request):
|
||||||
|
@ -6,7 +6,7 @@ from circuits.models import Circuit
|
|||||||
from dcim.models import Site, Rack, Device, RackReservation
|
from dcim.models import Site, Rack, Device, RackReservation
|
||||||
from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
|
from ipam.models import Aggregate, IPAddress, Prefix, VLAN, VRF
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from virtualization.models import VirtualMachine, Cluster
|
from virtualization.models import VirtualMachine, Cluster
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
@ -38,7 +38,7 @@ class TenantGroupView(generic.ObjectView):
|
|||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
tenants_table = tables.TenantTable(tenants, exclude=('group',))
|
tenants_table = tables.TenantTable(tenants, exclude=('group',))
|
||||||
paginate_table(tenants_table, request)
|
configure_table(tenants_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'tenants_table': tenants_table,
|
'tenants_table': tenants_table,
|
||||||
@ -184,7 +184,7 @@ class ContactGroupView(generic.ObjectView):
|
|||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
contacts_table = tables.ContactTable(contacts, exclude=('group',))
|
contacts_table = tables.ContactTable(contacts, exclude=('group',))
|
||||||
paginate_table(contacts_table, request)
|
configure_table(contacts_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'child_groups_table': child_groups_table,
|
'child_groups_table': child_groups_table,
|
||||||
@ -251,7 +251,7 @@ class ContactRoleView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
contacts_table = tables.ContactAssignmentTable(contact_assignments)
|
contacts_table = tables.ContactAssignmentTable(contact_assignments)
|
||||||
contacts_table.columns.hide('role')
|
contacts_table.columns.hide('role')
|
||||||
paginate_table(contacts_table, request)
|
configure_table(contacts_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'contacts_table': contacts_table,
|
'contacts_table': contacts_table,
|
||||||
@ -308,7 +308,7 @@ class ContactView(generic.ObjectView):
|
|||||||
)
|
)
|
||||||
assignments_table = tables.ContactAssignmentTable(contact_assignments)
|
assignments_table = tables.ContactAssignmentTable(contact_assignments)
|
||||||
assignments_table.columns.hide('contact')
|
assignments_table.columns.hide('contact')
|
||||||
paginate_table(assignments_table, request)
|
configure_table(assignments_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'assignments_table': assignments_table,
|
'assignments_table': assignments_table,
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.test import override_settings, TestCase
|
from django.test import override_settings
|
||||||
|
from django.test.client import RequestFactory
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
|
from dcim.models import Site
|
||||||
|
from dcim.tables import SiteTable
|
||||||
from users.preferences import UserPreference
|
from users.preferences import UserPreference
|
||||||
|
from utilities.tables import configure_table
|
||||||
|
from utilities.testing import TestCase
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_USER_PREFERENCES = {
|
DEFAULT_USER_PREFERENCES = {
|
||||||
@ -12,6 +18,7 @@ DEFAULT_USER_PREFERENCES = {
|
|||||||
|
|
||||||
|
|
||||||
class UserPreferencesTest(TestCase):
|
class UserPreferencesTest(TestCase):
|
||||||
|
user_permissions = ['dcim.view_site']
|
||||||
|
|
||||||
def test_userpreference(self):
|
def test_userpreference(self):
|
||||||
CHOICES = (
|
CHOICES = (
|
||||||
@ -37,3 +44,21 @@ class UserPreferencesTest(TestCase):
|
|||||||
userconfig = user.config
|
userconfig = user.config
|
||||||
|
|
||||||
self.assertEqual(userconfig.data, DEFAULT_USER_PREFERENCES)
|
self.assertEqual(userconfig.data, DEFAULT_USER_PREFERENCES)
|
||||||
|
|
||||||
|
def test_table_ordering(self):
|
||||||
|
url = reverse('dcim:site_list')
|
||||||
|
response = self.client.get(f"{url}?sort=status")
|
||||||
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
|
# Check that table ordering preference has been recorded
|
||||||
|
self.user.refresh_from_db()
|
||||||
|
ordering = self.user.config.get(f'tables.SiteTable.ordering')
|
||||||
|
self.assertEqual(ordering, ['status'])
|
||||||
|
|
||||||
|
# Check that a recorded preference is honored by default
|
||||||
|
self.user.config.set(f'tables.SiteTable.ordering', ['-status'], commit=True)
|
||||||
|
table = SiteTable(Site.objects.all())
|
||||||
|
request = RequestFactory().get(url)
|
||||||
|
request.user = self.user
|
||||||
|
configure_table(table, request)
|
||||||
|
self.assertEqual(table.order_by, ('-status',))
|
||||||
|
@ -5,14 +5,23 @@ from .columns import *
|
|||||||
from .tables import *
|
from .tables import *
|
||||||
|
|
||||||
|
|
||||||
#
|
def configure_table(table, request):
|
||||||
# Pagination
|
|
||||||
#
|
|
||||||
|
|
||||||
def paginate_table(table, request):
|
|
||||||
"""
|
"""
|
||||||
Paginate a table given a request context.
|
Paginate a table given a request context.
|
||||||
"""
|
"""
|
||||||
|
# Save ordering preference
|
||||||
|
if request.user.is_authenticated:
|
||||||
|
table_name = table.__class__.__name__
|
||||||
|
if table.prefixed_order_by_field in request.GET:
|
||||||
|
# If an ordering has been specified as a query parameter, save it as the
|
||||||
|
# user's preferred ordering for this table.
|
||||||
|
ordering = request.GET.getlist(table.prefixed_order_by_field)
|
||||||
|
request.user.config.set(f'tables.{table_name}.ordering', ordering, commit=True)
|
||||||
|
elif ordering := request.user.config.get(f'tables.{table_name}.ordering'):
|
||||||
|
# If no ordering has been specified, set the preferred ordering (if any).
|
||||||
|
table.order_by = ordering
|
||||||
|
|
||||||
|
# Paginate the table results
|
||||||
paginate = {
|
paginate = {
|
||||||
'paginator_class': EnhancedPaginator,
|
'paginator_class': EnhancedPaginator,
|
||||||
'per_page': get_paginate_count(request)
|
'per_page': get_paginate_count(request)
|
||||||
|
@ -11,7 +11,7 @@ from extras.views import ObjectConfigContextView
|
|||||||
from ipam.models import IPAddress, Service
|
from ipam.models import IPAddress, Service
|
||||||
from ipam.tables import AssignedIPAddressesTable, InterfaceVLANTable
|
from ipam.tables import AssignedIPAddressesTable, InterfaceVLANTable
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
from .models import Cluster, ClusterGroup, ClusterType, VirtualMachine, VMInterface
|
||||||
@ -41,7 +41,7 @@ class ClusterTypeView(generic.ObjectView):
|
|||||||
vm_count=count_related(VirtualMachine, 'cluster')
|
vm_count=count_related(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
clusters_table = tables.ClusterTable(clusters, exclude=('type',))
|
clusters_table = tables.ClusterTable(clusters, exclude=('type',))
|
||||||
paginate_table(clusters_table, request)
|
configure_table(clusters_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'clusters_table': clusters_table,
|
'clusters_table': clusters_table,
|
||||||
@ -103,7 +103,7 @@ class ClusterGroupView(generic.ObjectView):
|
|||||||
vm_count=count_related(VirtualMachine, 'cluster')
|
vm_count=count_related(VirtualMachine, 'cluster')
|
||||||
)
|
)
|
||||||
clusters_table = tables.ClusterTable(clusters, exclude=('group',))
|
clusters_table = tables.ClusterTable(clusters, exclude=('group',))
|
||||||
paginate_table(clusters_table, request)
|
configure_table(clusters_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'clusters_table': clusters_table,
|
'clusters_table': clusters_table,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
from netbox.views import generic
|
from netbox.views import generic
|
||||||
from utilities.tables import paginate_table
|
from utilities.tables import configure_table
|
||||||
from utilities.utils import count_related
|
from utilities.utils import count_related
|
||||||
from . import filtersets, forms, tables
|
from . import filtersets, forms, tables
|
||||||
from .models import *
|
from .models import *
|
||||||
@ -31,7 +31,7 @@ class WirelessLANGroupView(generic.ObjectView):
|
|||||||
group=instance
|
group=instance
|
||||||
)
|
)
|
||||||
wirelesslans_table = tables.WirelessLANTable(wirelesslans, exclude=('group',))
|
wirelesslans_table = tables.WirelessLANTable(wirelesslans, exclude=('group',))
|
||||||
paginate_table(wirelesslans_table, request)
|
configure_table(wirelesslans_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'wirelesslans_table': wirelesslans_table,
|
'wirelesslans_table': wirelesslans_table,
|
||||||
@ -99,7 +99,7 @@ class WirelessLANView(generic.ObjectView):
|
|||||||
wireless_lans=instance
|
wireless_lans=instance
|
||||||
)
|
)
|
||||||
interfaces_table = tables.WirelessLANInterfacesTable(attached_interfaces)
|
interfaces_table = tables.WirelessLANInterfacesTable(attached_interfaces)
|
||||||
paginate_table(interfaces_table, request)
|
configure_table(interfaces_table, request)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'interfaces_table': interfaces_table,
|
'interfaces_table': interfaces_table,
|
||||||
|
Reference in New Issue
Block a user