From 7357f953eba60b1ebd54ef498c0dc390f2389cc9 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Wed, 13 Mar 2024 16:13:06 -0400 Subject: [PATCH] Closes #15413: Enable caching of object attributes in search index --- netbox/netbox/search/__init__.py | 27 ++++++++++++++++++++++++++- netbox/netbox/tables/tables.py | 8 +++++--- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/netbox/netbox/search/__init__.py b/netbox/netbox/search/__init__.py index 590188f21..76898be13 100644 --- a/netbox/netbox/search/__init__.py +++ b/netbox/netbox/search/__init__.py @@ -1,6 +1,9 @@ from collections import namedtuple +from decimal import Decimal +from django.core.exceptions import FieldDoesNotExist from django.db import models +from netaddr import IPAddress, IPNetwork from ipam.fields import IPAddressField, IPNetworkField from netbox.registry import registry @@ -56,6 +59,24 @@ class SearchIndex: return FieldTypes.INTEGER return FieldTypes.STRING + @staticmethod + def get_attr_type(instance, field_name): + """ + Return the data type of the specified object attribute. + """ + value = getattr(instance, field_name) + if type(value) is str: + return FieldTypes.STRING + if type(value) is int: + return FieldTypes.INTEGER + if type(value) in (float, Decimal): + return FieldTypes.FLOAT + if type(value) is IPNetwork: + return FieldTypes.CIDR + if type(value) is IPAddress: + return FieldTypes.INET + return FieldTypes.STRING + @staticmethod def get_field_value(instance, field_name): """ @@ -82,7 +103,11 @@ class SearchIndex: # Capture built-in fields for name, weight in cls.fields: - type_ = cls.get_field_type(instance, name) + try: + type_ = cls.get_field_type(instance, name) + except FieldDoesNotExist: + # Not a concrete field; handle as an object attribute + type_ = cls.get_attr_type(instance, name) value = cls.get_field_value(instance, name) if type_ and value: values.append( diff --git a/netbox/netbox/tables/tables.py b/netbox/netbox/tables/tables.py index afef74752..31502f6c5 100644 --- a/netbox/netbox/tables/tables.py +++ b/netbox/netbox/tables/tables.py @@ -263,9 +263,11 @@ class SearchTable(tables.Table): super().__init__(data, **kwargs) def render_field(self, value, record): - if hasattr(record.object, value): - return title(record.object._meta.get_field(value).verbose_name) - return value + try: + model_field = record.object._meta.get_field(value) + return title(model_field.verbose_name) + except FieldDoesNotExist: + return value def render_value(self, value): if not self.highlight: