From 2c19390d7c69c3c930def43153567b3cd807a379 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Thu, 7 May 2020 17:20:32 -0400 Subject: [PATCH] Introduce CustomFieldManager (WIP) --- .../migrations/0042_customfield_manager.py | 20 ++++++++++ netbox/extras/models/customfields.py | 38 +++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 netbox/extras/migrations/0042_customfield_manager.py diff --git a/netbox/extras/migrations/0042_customfield_manager.py b/netbox/extras/migrations/0042_customfield_manager.py new file mode 100644 index 000000000..7d80b567a --- /dev/null +++ b/netbox/extras/migrations/0042_customfield_manager.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.5 on 2020-05-07 21:06 + +from django.db import migrations +import extras.models.customfields + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0041_tag_description'), + ] + + operations = [ + migrations.AlterModelManagers( + name='customfield', + managers=[ + ('objects', extras.models.customfields.CustomFieldManager()), + ], + ), + ] diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 47bccd98a..f00a52a5d 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -43,10 +43,7 @@ class CustomFieldModel(models.Model): """ Return a dictionary of custom fields for a single object in the form {: value}. """ - - # Find all custom fields applicable to this type of object - content_type = ContentType.objects.get_for_model(self) - fields = CustomField.objects.filter(obj_type=content_type) + fields = CustomField.objects.get_for_model(self) # If the object exists, populate its custom fields with values if hasattr(self, 'pk'): @@ -57,6 +54,37 @@ class CustomFieldModel(models.Model): return OrderedDict([(field, None) for field in fields]) +class CustomFieldManager(models.Manager): + use_in_migrations = True + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Initialize a cache for fetched CustomFields + self._cache = {} + + def get_for_model(self, model): + """ + Return all CustomFields assigned to the given model. + """ + model = model._meta.concrete_model + + # First try to return from cache + try: + return self._cache[model] + except KeyError: + pass + + # Fetch from the database if the model's CustomFields have not been cached + content_type = ContentType.objects.get_for_model(model) + customfields = CustomField.objects.filter(obj_type=content_type) + + # Cache the retrieved CustomFields + self._cache[model] = customfields + + return customfields + + class CustomField(models.Model): obj_type = models.ManyToManyField( to=ContentType, @@ -106,6 +134,8 @@ class CustomField(models.Model): help_text='Fields with higher weights appear lower in a form.' ) + objects = CustomFieldManager() + class Meta: ordering = ['weight', 'name']