mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Drop add_prefetch from BaseTable; improve dynamic prefetching for table querysets
This commit is contained in:
@ -40,8 +40,6 @@ class ConsoleConnectionTable(BaseTable):
|
|||||||
verbose_name='Reachable'
|
verbose_name='Reachable'
|
||||||
)
|
)
|
||||||
|
|
||||||
add_prefetch = False
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = ConsolePort
|
model = ConsolePort
|
||||||
fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable')
|
fields = ('device', 'name', 'console_server', 'console_server_port', 'reachable')
|
||||||
@ -72,8 +70,6 @@ class PowerConnectionTable(BaseTable):
|
|||||||
verbose_name='Reachable'
|
verbose_name='Reachable'
|
||||||
)
|
)
|
||||||
|
|
||||||
add_prefetch = False
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = PowerPort
|
model = PowerPort
|
||||||
fields = ('device', 'name', 'pdu', 'outlet', 'reachable')
|
fields = ('device', 'name', 'pdu', 'outlet', 'reachable')
|
||||||
@ -107,8 +103,6 @@ class InterfaceConnectionTable(BaseTable):
|
|||||||
verbose_name='Reachable'
|
verbose_name='Reachable'
|
||||||
)
|
)
|
||||||
|
|
||||||
add_prefetch = False
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = Interface
|
model = Interface
|
||||||
fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable')
|
fields = ('device_a', 'interface_a', 'device_b', 'interface_b', 'reachable')
|
||||||
|
@ -280,8 +280,6 @@ class PrefixTable(BaseTable):
|
|||||||
verbose_name='Pool'
|
verbose_name='Pool'
|
||||||
)
|
)
|
||||||
|
|
||||||
add_prefetch = False
|
|
||||||
|
|
||||||
class Meta(BaseTable.Meta):
|
class Meta(BaseTable.Meta):
|
||||||
model = Prefix
|
model = Prefix
|
||||||
fields = (
|
fields = (
|
||||||
|
@ -14,11 +14,6 @@ class BaseTable(tables.Table):
|
|||||||
|
|
||||||
:param user: Personalize table display for the given user (optional). Has no effect if AnonymousUser is passed.
|
:param user: Personalize table display for the given user (optional). Has no effect if AnonymousUser is passed.
|
||||||
"""
|
"""
|
||||||
# By default, modify the queryset passed to the table upon initialization to automatically prefetch related
|
|
||||||
# data. Set this to False if it's necessary to avoid modifying the queryset (e.g. to accommodate
|
|
||||||
# PrefixQuerySet.annotate_depth()).
|
|
||||||
add_prefetch = True
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
attrs = {
|
attrs = {
|
||||||
'class': 'table table-hover table-headings',
|
'class': 'table table-hover table-headings',
|
||||||
@ -61,18 +56,28 @@ class BaseTable(tables.Table):
|
|||||||
self.sequence.append('actions')
|
self.sequence.append('actions')
|
||||||
|
|
||||||
# Dynamically update the table's QuerySet to ensure related fields are pre-fetched
|
# Dynamically update the table's QuerySet to ensure related fields are pre-fetched
|
||||||
if self.add_prefetch and isinstance(self.data, TableQuerysetData):
|
if isinstance(self.data, TableQuerysetData):
|
||||||
model = getattr(self.Meta, 'model')
|
|
||||||
prefetch_fields = []
|
prefetch_fields = []
|
||||||
for column in self.columns:
|
for column in self.columns:
|
||||||
if column.visible:
|
if column.visible:
|
||||||
field_path = column.accessor.split('.')
|
model = getattr(self.Meta, 'model')
|
||||||
|
accessor = column.accessor
|
||||||
|
prefetch_path = []
|
||||||
|
for field_name in accessor.split(accessor.SEPARATOR):
|
||||||
try:
|
try:
|
||||||
model_field = model._meta.get_field(field_path[0])
|
field = model._meta.get_field(field_name)
|
||||||
if isinstance(model_field, (RelatedField, GenericForeignKey)):
|
|
||||||
prefetch_fields.append('__'.join(field_path))
|
|
||||||
except FieldDoesNotExist:
|
except FieldDoesNotExist:
|
||||||
pass
|
break
|
||||||
|
if isinstance(field, RelatedField):
|
||||||
|
# Follow ForeignKeys to the related model
|
||||||
|
prefetch_path.append(field_name)
|
||||||
|
model = field.remote_field.model
|
||||||
|
elif isinstance(field, GenericForeignKey):
|
||||||
|
# Can't prefetch beyond a GenericForeignKey
|
||||||
|
prefetch_path.append(field_name)
|
||||||
|
break
|
||||||
|
if prefetch_path:
|
||||||
|
prefetch_fields.append('__'.join(prefetch_path))
|
||||||
self.data.data = self.data.data.prefetch_related(None).prefetch_related(*prefetch_fields)
|
self.data.data = self.data.data.prefetch_related(None).prefetch_related(*prefetch_fields)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
Reference in New Issue
Block a user