search.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import uuid
  2. from django.db import models
  3. from django.utils.translation import gettext_lazy as _
  4. from netbox.search.utils import get_indexer
  5. from netbox.registry import registry
  6. from utilities.fields import RestrictedGenericForeignKey
  7. from utilities.utils import content_type_identifier
  8. from ..fields import CachedValueField
  9. __all__ = (
  10. 'CachedValue',
  11. )
  12. class CachedValue(models.Model):
  13. id = models.UUIDField(
  14. primary_key=True,
  15. default=uuid.uuid4,
  16. editable=False
  17. )
  18. timestamp = models.DateTimeField(
  19. verbose_name=_('timestamp'),
  20. auto_now_add=True,
  21. editable=False
  22. )
  23. object_type = models.ForeignKey(
  24. to='contenttypes.ContentType',
  25. on_delete=models.CASCADE,
  26. related_name='+'
  27. )
  28. object_id = models.PositiveBigIntegerField()
  29. object = RestrictedGenericForeignKey(
  30. ct_field='object_type',
  31. fk_field='object_id'
  32. )
  33. field = models.CharField(
  34. verbose_name=_('field'),
  35. max_length=200
  36. )
  37. type = models.CharField(
  38. verbose_name=_('type'),
  39. max_length=30
  40. )
  41. value = CachedValueField(
  42. verbose_name=_('value'),
  43. )
  44. weight = models.PositiveSmallIntegerField(
  45. verbose_name=_('weight'),
  46. default=1000
  47. )
  48. _netbox_private = True
  49. class Meta:
  50. ordering = ('weight', 'object_type', 'value', 'object_id')
  51. verbose_name = _('cached value')
  52. verbose_name_plural = _('cached values')
  53. indexes = (
  54. models.Index(fields=('object_type', 'object_id'), name='extras_cachedvalue_object'),
  55. )
  56. def __str__(self):
  57. return f'{self.object_type} {self.object_id}: {self.field}={self.value}'
  58. @property
  59. def display_attrs(self):
  60. """
  61. Render any display attributes associated with this search result.
  62. """
  63. indexer = get_indexer(self.object_type)
  64. attrs = {}
  65. for attr in indexer.display_attrs:
  66. name = self.object._meta.get_field(attr).verbose_name
  67. if value := getattr(self.object, attr):
  68. if display_func := getattr(self.object, f'get_{attr}_display', None):
  69. attrs[name] = display_func()
  70. else:
  71. attrs[name] = value
  72. return attrs