mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-27 02:48:38 -06:00
Add support for custom fields in tables
This commit is contained in:
parent
c1e56a3717
commit
a8cdbcfd01
@ -1,12 +1,15 @@
|
|||||||
import django_tables2 as tables
|
import django_tables2 as tables
|
||||||
from django.contrib.auth.models import AnonymousUser
|
from django.contrib.auth.models import AnonymousUser
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import FieldDoesNotExist
|
from django.core.exceptions import FieldDoesNotExist
|
||||||
|
from django.db.models import Func, F, Value
|
||||||
from django.db.models.fields.related import RelatedField
|
from django.db.models.fields.related import RelatedField
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils.safestring import mark_safe
|
from django.utils.safestring import mark_safe
|
||||||
from django_tables2.data import TableQuerysetData
|
from django_tables2.data import TableQuerysetData
|
||||||
|
|
||||||
|
from extras.models import CustomField
|
||||||
|
|
||||||
class BaseTable(tables.Table):
|
class BaseTable(tables.Table):
|
||||||
"""
|
"""
|
||||||
@ -14,12 +17,25 @@ 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.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
attrs = {
|
attrs = {
|
||||||
'class': 'table table-hover table-headings',
|
'class': 'table table-hover table-headings',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, user=None, **kwargs):
|
def __init__(self, *args, user=None, **kwargs):
|
||||||
|
# Add custom field columns
|
||||||
|
obj_type = ContentType.objects.get_for_model(self._meta.model)
|
||||||
|
custom_fields = {}
|
||||||
|
|
||||||
|
for cf in CustomField.objects.filter(content_types=obj_type):
|
||||||
|
name = 'cf_{}'.format(cf.name)
|
||||||
|
label = cf.label if cf.label != '' else cf.name
|
||||||
|
self.base_columns[name] = CustomFieldColumn(verbose_name=label)
|
||||||
|
custom_fields[name] = cf
|
||||||
|
self._meta.fields += tuple(custom_fields.keys())
|
||||||
|
|
||||||
|
# Init table
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
# Set default empty_text if none was provided
|
# Set default empty_text if none was provided
|
||||||
@ -57,6 +73,12 @@ class BaseTable(tables.Table):
|
|||||||
|
|
||||||
# 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 isinstance(self.data, TableQuerysetData):
|
if isinstance(self.data, TableQuerysetData):
|
||||||
|
# Extract custom field values
|
||||||
|
cf_fields = {}
|
||||||
|
for key, cf in custom_fields.items():
|
||||||
|
cf_fields[key] = Func(F('custom_field_data'), Value(cf.name), function='jsonb_extract_path_text')
|
||||||
|
self.data.data = self.data.data.annotate(**cf_fields)
|
||||||
|
|
||||||
prefetch_fields = []
|
prefetch_fields = []
|
||||||
for column in self.columns:
|
for column in self.columns:
|
||||||
if column.visible:
|
if column.visible:
|
||||||
@ -267,3 +289,21 @@ class TagColumn(tables.TemplateColumn):
|
|||||||
template_code=self.template_code,
|
template_code=self.template_code,
|
||||||
extra_context={'url_name': url_name}
|
extra_context={'url_name': url_name}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class CustomFieldColumn(tables.Column):
|
||||||
|
"""
|
||||||
|
Display custom fields in the appropriate format.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def render(self, record, bound_column, value):
|
||||||
|
if value:
|
||||||
|
if isinstance(value, list):
|
||||||
|
template = ''
|
||||||
|
for v in value:
|
||||||
|
template += f'<span class="label label-default">{v}</span> '
|
||||||
|
else:
|
||||||
|
template = value
|
||||||
|
return mark_safe(template)
|
||||||
|
return self.default
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user