Просмотр исходного кода

Closes #22877: Improve caching logic when retrieving custom fields via get_for_model()

Jeremy Stretch 2 недель назад
Родитель
Сommit
b1ee8297d2

+ 21 - 21
netbox/circuits/tests/query_counts.json

@@ -1,24 +1,24 @@
 {
-  "circuit:api_list_objects": 16,
-  "circuit:list_objects_with_permission": 22,
-  "circuitgroup:api_list_objects": 13,
-  "circuitgroup:list_objects_with_permission": 20,
+  "circuit:api_list_objects": 15,
+  "circuit:list_objects_with_permission": 19,
+  "circuitgroup:api_list_objects": 12,
+  "circuitgroup:list_objects_with_permission": 17,
   "circuitgroupassignment:api_list_objects": 17,
-  "circuitgroupassignment:list_objects_with_permission": 26,
-  "circuittermination:api_list_objects": 18,
-  "circuittermination:list_objects_with_permission": 24,
-  "circuittype:api_list_objects": 13,
-  "circuittype:list_objects_with_permission": 20,
-  "provider:api_list_objects": 15,
-  "provider:list_objects_with_permission": 20,
-  "provideraccount:api_list_objects": 14,
-  "provideraccount:list_objects_with_permission": 21,
-  "providernetwork:api_list_objects": 14,
-  "providernetwork:list_objects_with_permission": 21,
-  "virtualcircuit:api_list_objects": 16,
-  "virtualcircuit:list_objects_with_permission": 24,
-  "virtualcircuittermination:api_list_objects": 17,
-  "virtualcircuittermination:list_objects_with_permission": 23,
-  "virtualcircuittype:api_list_objects": 13,
-  "virtualcircuittype:list_objects_with_permission": 20
+  "circuitgroupassignment:list_objects_with_permission": 23,
+  "circuittermination:api_list_objects": 17,
+  "circuittermination:list_objects_with_permission": 21,
+  "circuittype:api_list_objects": 12,
+  "circuittype:list_objects_with_permission": 17,
+  "provider:api_list_objects": 14,
+  "provider:list_objects_with_permission": 17,
+  "provideraccount:api_list_objects": 13,
+  "provideraccount:list_objects_with_permission": 18,
+  "providernetwork:api_list_objects": 13,
+  "providernetwork:list_objects_with_permission": 18,
+  "virtualcircuit:api_list_objects": 15,
+  "virtualcircuit:list_objects_with_permission": 21,
+  "virtualcircuittermination:api_list_objects": 16,
+  "virtualcircuittermination:list_objects_with_permission": 20,
+  "virtualcircuittype:api_list_objects": 12,
+  "virtualcircuittype:list_objects_with_permission": 17
 }

+ 3 - 3
netbox/core/tests/query_counts.json

@@ -1,8 +1,8 @@
 {
   "datafile:api_list_objects": 10,
-  "datafile:list_objects_with_permission": 18,
-  "datasource:api_list_objects": 12,
-  "datasource:list_objects_with_permission": 20,
+  "datafile:list_objects_with_permission": 17,
+  "datasource:api_list_objects": 11,
+  "datasource:list_objects_with_permission": 17,
   "job:api_list_objects": 12,
   "job:list_objects_with_permission": 19
 }

+ 70 - 70
netbox/dcim/tests/query_counts.json

@@ -1,86 +1,86 @@
 {
-  "cable:api_list_objects": 24,
-  "cable:list_objects_with_permission": 24,
-  "cablebundle:api_list_objects": 13,
-  "cablebundle:list_objects_with_permission": 20,
+  "cable:api_list_objects": 23,
+  "cable:list_objects_with_permission": 21,
+  "cablebundle:api_list_objects": 12,
+  "cablebundle:list_objects_with_permission": 17,
   "cabletermination:api_list_objects": 16,
   "consoleconnection:list_objects_with_permission": 29,
-  "consoleport:api_list_objects": 14,
-  "consoleport:list_objects_with_permission": 21,
+  "consoleport:api_list_objects": 13,
+  "consoleport:list_objects_with_permission": 18,
   "consoleporttemplate:api_list_objects": 11,
-  "consoleserverport:api_list_objects": 14,
-  "consoleserverport:list_objects_with_permission": 21,
+  "consoleserverport:api_list_objects": 13,
+  "consoleserverport:list_objects_with_permission": 18,
   "consoleserverporttemplate:api_list_objects": 11,
-  "device:api_list_objects": 20,
-  "device:list_objects_with_permission": 25,
-  "devicebay:api_list_objects": 14,
-  "devicebay:list_objects_with_permission": 21,
+  "device:api_list_objects": 19,
+  "device:list_objects_with_permission": 22,
+  "devicebay:api_list_objects": 13,
+  "devicebay:list_objects_with_permission": 18,
   "devicebaytemplate:api_list_objects": 11,
-  "devicerole:api_list_objects": 13,
-  "devicerole:list_objects_with_permission": 20,
-  "devicetype:api_list_objects": 14,
-  "devicetype:list_objects_with_permission": 21,
-  "frontport:api_list_objects": 15,
-  "frontport:list_objects_with_permission": 25,
+  "devicerole:api_list_objects": 12,
+  "devicerole:list_objects_with_permission": 17,
+  "devicetype:api_list_objects": 13,
+  "devicetype:list_objects_with_permission": 18,
+  "frontport:api_list_objects": 14,
+  "frontport:list_objects_with_permission": 22,
   "frontporttemplate:api_list_objects": 12,
-  "interface:api_list_objects": 23,
-  "interface:list_objects_with_permission": 21,
+  "interface:api_list_objects": 22,
+  "interface:list_objects_with_permission": 18,
   "interfaceconnection:list_objects_with_permission": 41,
   "interfacetemplate:api_list_objects": 11,
-  "inventoryitem:api_list_objects": 20,
-  "inventoryitem:list_objects_with_permission": 23,
-  "inventoryitemrole:api_list_objects": 13,
-  "inventoryitemrole:list_objects_with_permission": 20,
+  "inventoryitem:api_list_objects": 19,
+  "inventoryitem:list_objects_with_permission": 20,
+  "inventoryitemrole:api_list_objects": 12,
+  "inventoryitemrole:list_objects_with_permission": 17,
   "inventoryitemtemplate:api_list_objects": 13,
-  "location:api_list_objects": 15,
-  "location:list_objects_with_permission": 22,
-  "macaddress:api_list_objects": 17,
-  "macaddress:list_objects_with_permission": 24,
-  "manufacturer:api_list_objects": 13,
-  "manufacturer:list_objects_with_permission": 20,
-  "module:api_list_objects": 18,
-  "module:list_objects_with_permission": 24,
-  "modulebay:api_list_objects": 15,
-  "modulebay:list_objects_with_permission": 21,
+  "location:api_list_objects": 14,
+  "location:list_objects_with_permission": 19,
+  "macaddress:api_list_objects": 16,
+  "macaddress:list_objects_with_permission": 21,
+  "manufacturer:api_list_objects": 12,
+  "manufacturer:list_objects_with_permission": 17,
+  "module:api_list_objects": 17,
+  "module:list_objects_with_permission": 21,
+  "modulebay:api_list_objects": 14,
+  "modulebay:list_objects_with_permission": 18,
   "modulebaytemplate:api_list_objects": 11,
-  "moduletype:api_list_objects": 14,
-  "moduletype:list_objects_with_permission": 22,
-  "moduletypeprofile:api_list_objects": 13,
-  "moduletypeprofile:list_objects_with_permission": 20,
-  "platform:api_list_objects": 13,
-  "platform:list_objects_with_permission": 21,
+  "moduletype:api_list_objects": 13,
+  "moduletype:list_objects_with_permission": 19,
+  "moduletypeprofile:api_list_objects": 12,
+  "moduletypeprofile:list_objects_with_permission": 17,
+  "platform:api_list_objects": 12,
+  "platform:list_objects_with_permission": 18,
   "powerconnection:list_objects_with_permission": 29,
-  "powerfeed:api_list_objects": 15,
-  "powerfeed:list_objects_with_permission": 22,
-  "poweroutlet:api_list_objects": 14,
-  "poweroutlet:list_objects_with_permission": 22,
+  "powerfeed:api_list_objects": 14,
+  "powerfeed:list_objects_with_permission": 19,
+  "poweroutlet:api_list_objects": 13,
+  "poweroutlet:list_objects_with_permission": 19,
   "poweroutlettemplate:api_list_objects": 11,
-  "powerpanel:api_list_objects": 15,
-  "powerpanel:list_objects_with_permission": 22,
-  "powerport:api_list_objects": 14,
-  "powerport:list_objects_with_permission": 21,
+  "powerpanel:api_list_objects": 14,
+  "powerpanel:list_objects_with_permission": 19,
+  "powerport:api_list_objects": 13,
+  "powerport:list_objects_with_permission": 18,
   "powerporttemplate:api_list_objects": 11,
-  "rack:api_list_objects": 17,
-  "rack:list_objects_with_permission": 29,
-  "rackgroup:api_list_objects": 13,
-  "rackgroup:list_objects_with_permission": 20,
-  "rackreservation:api_list_objects": 15,
-  "rackreservation:list_objects_with_permission": 23,
-  "rackrole:api_list_objects": 13,
-  "rackrole:list_objects_with_permission": 20,
-  "racktype:api_list_objects": 14,
-  "racktype:list_objects_with_permission": 21,
-  "rearport:api_list_objects": 15,
-  "rearport:list_objects_with_permission": 22,
+  "rack:api_list_objects": 16,
+  "rack:list_objects_with_permission": 26,
+  "rackgroup:api_list_objects": 12,
+  "rackgroup:list_objects_with_permission": 17,
+  "rackreservation:api_list_objects": 14,
+  "rackreservation:list_objects_with_permission": 20,
+  "rackrole:api_list_objects": 12,
+  "rackrole:list_objects_with_permission": 17,
+  "racktype:api_list_objects": 13,
+  "racktype:list_objects_with_permission": 18,
+  "rearport:api_list_objects": 14,
+  "rearport:list_objects_with_permission": 19,
   "rearporttemplate:api_list_objects": 12,
-  "region:api_list_objects": 13,
-  "region:list_objects_with_permission": 20,
-  "site:api_list_objects": 17,
-  "site:list_objects_with_permission": 22,
-  "sitegroup:api_list_objects": 13,
-  "sitegroup:list_objects_with_permission": 20,
-  "virtualchassis:api_list_objects": 16,
-  "virtualchassis:list_objects_with_permission": 21,
-  "virtualdevicecontext:api_list_objects": 14,
-  "virtualdevicecontext:list_objects_with_permission": 20
+  "region:api_list_objects": 12,
+  "region:list_objects_with_permission": 17,
+  "site:api_list_objects": 16,
+  "site:list_objects_with_permission": 19,
+  "sitegroup:api_list_objects": 12,
+  "sitegroup:list_objects_with_permission": 17,
+  "virtualchassis:api_list_objects": 15,
+  "virtualchassis:list_objects_with_permission": 18,
+  "virtualdevicecontext:api_list_objects": 13,
+  "virtualdevicecontext:list_objects_with_permission": 17
 }

+ 4 - 2
netbox/extras/models/customfields.py

@@ -71,10 +71,12 @@ class CustomFieldManager(models.Manager.from_queryset(RestrictedQuerySet)):
         """
         Return all CustomFields assigned to the given model.
         """
-        # Check the request cache before hitting the database
+        # Check the request cache before hitting the database. Test the cached value against None
+        # rather than for truthiness: a model with no custom fields caches an empty QuerySet, which
+        # would otherwise be treated as a miss and re-queried on every call.
         cache = query_cache.get()
         if cache is not None:
-            if custom_fields := cache['custom_fields'].get(model._meta.model):
+            if (custom_fields := cache['custom_fields'].get(model._meta.model)) is not None:
                 return custom_fields
 
         content_type = ObjectType.objects.get_for_model(model._meta.concrete_model)

+ 7 - 7
netbox/extras/tests/query_counts.json

@@ -4,7 +4,7 @@
   "configcontext:api_list_objects": 22,
   "configcontext:list_objects_with_permission": 16,
   "configcontextprofile:api_list_objects": 12,
-  "configcontextprofile:list_objects_with_permission": 19,
+  "configcontextprofile:list_objects_with_permission": 16,
   "configtemplate:api_list_objects": 10,
   "configtemplate:list_objects_with_permission": 17,
   "customfield:api_list_objects": 10,
@@ -13,14 +13,14 @@
   "customfieldchoiceset:list_objects_with_permission": 16,
   "customlink:api_list_objects": 10,
   "customlink:list_objects_with_permission": 18,
-  "eventrule:api_list_objects": 16,
-  "eventrule:list_objects_with_permission": 23,
+  "eventrule:api_list_objects": 15,
+  "eventrule:list_objects_with_permission": 20,
   "exporttemplate:api_list_objects": 10,
   "exporttemplate:list_objects_with_permission": 19,
   "imageattachment:api_list_objects": 11,
   "imageattachment:list_objects_with_permission": 21,
-  "journalentry:api_list_objects": 16,
-  "journalentry:list_objects_with_permission": 24,
+  "journalentry:api_list_objects": 15,
+  "journalentry:list_objects_with_permission": 21,
   "notification:api_list_objects": 12,
   "notificationgroup:api_list_objects": 11,
   "notificationgroup:list_objects_with_permission": 18,
@@ -32,6 +32,6 @@
   "tag:api_list_objects": 10,
   "tag:list_objects_with_permission": 18,
   "taggeditem:api_list_objects": 12,
-  "webhook:api_list_objects": 13,
-  "webhook:list_objects_with_permission": 20
+  "webhook:api_list_objects": 12,
+  "webhook:list_objects_with_permission": 17
 }

+ 18 - 0
netbox/extras/tests/test_customfields.py

@@ -1,5 +1,6 @@
 import datetime
 import json
+from collections import defaultdict
 from decimal import Decimal
 from unittest.mock import patch
 
@@ -16,6 +17,7 @@ from extras.choices import *
 from extras.models import CustomField, CustomFieldChoiceSet
 from ipam.models import VLAN
 from netbox.choices import CSVDelimiterChoices, ImportFormatChoices
+from netbox.context import query_cache
 from utilities.testing import APITestCase, TestCase
 from virtualization.models import VirtualMachine
 
@@ -826,6 +828,22 @@ class CustomFieldManagerTestCase(TestCase):
         self.assertEqual(CustomField.objects.get_for_model(Site).count(), 1)
         self.assertEqual(CustomField.objects.get_for_model(VirtualMachine).count(), 0)
 
+    def test_get_for_model_caches_models_with_no_custom_fields(self):
+        """
+        A model with no custom fields assigned must be served from the request cache like any other.
+        An empty QuerySet is falsy, so testing the cached value for truthiness would treat it as a
+        miss and re-query on every call.
+        """
+        token = query_cache.set(defaultdict(dict))
+        self.addCleanup(query_cache.reset, token)
+
+        # Site has one custom field assigned, VirtualMachine none
+        for model in (Site, VirtualMachine):
+            # Prime the cache, iterating so that the QuerySet's own result cache is populated too
+            list(CustomField.objects.get_for_model(model))
+            with self.assertNumQueries(0):
+                list(CustomField.objects.get_for_model(model))
+
 
 class CustomFieldAPITestCase(APITestCase):
 

+ 32 - 32
netbox/ipam/tests/query_counts.json

@@ -1,37 +1,37 @@
 {
-  "aggregate:api_list_objects": 14,
-  "aggregate:list_objects_with_permission": 24,
-  "asn:api_list_objects": 18,
-  "asn:list_objects_with_permission": 31,
-  "asnrange:api_list_objects": 15,
-  "asnrange:list_objects_with_permission": 22,
-  "fhrpgroup:api_list_objects": 14,
-  "fhrpgroup:list_objects_with_permission": 21,
+  "aggregate:api_list_objects": 13,
+  "aggregate:list_objects_with_permission": 21,
+  "asn:api_list_objects": 17,
+  "asn:list_objects_with_permission": 28,
+  "asnrange:api_list_objects": 14,
+  "asnrange:list_objects_with_permission": 19,
+  "fhrpgroup:api_list_objects": 13,
+  "fhrpgroup:list_objects_with_permission": 18,
   "fhrpgroupassignment:api_list_objects": 18,
-  "ipaddress:api_list_objects": 14,
-  "ipaddress:list_objects_with_permission": 21,
-  "iprange:api_list_objects": 13,
-  "iprange:list_objects_with_permission": 20,
-  "prefix:api_list_objects": 13,
-  "prefix:list_objects_with_permission": 29,
-  "rir:api_list_objects": 13,
-  "rir:list_objects_with_permission": 20,
-  "role:api_list_objects": 13,
-  "role:list_objects_with_permission": 20,
-  "routetarget:api_list_objects": 13,
-  "routetarget:list_objects_with_permission": 21,
-  "service:api_list_objects": 16,
-  "service:list_objects_with_permission": 21,
-  "servicetemplate:api_list_objects": 13,
-  "servicetemplate:list_objects_with_permission": 20,
-  "vlan:api_list_objects": 15,
-  "vlan:list_objects_with_permission": 24,
-  "vlangroup:api_list_objects": 13,
-  "vlangroup:list_objects_with_permission": 25,
+  "ipaddress:api_list_objects": 13,
+  "ipaddress:list_objects_with_permission": 18,
+  "iprange:api_list_objects": 12,
+  "iprange:list_objects_with_permission": 17,
+  "prefix:api_list_objects": 12,
+  "prefix:list_objects_with_permission": 26,
+  "rir:api_list_objects": 12,
+  "rir:list_objects_with_permission": 17,
+  "role:api_list_objects": 12,
+  "role:list_objects_with_permission": 17,
+  "routetarget:api_list_objects": 12,
+  "routetarget:list_objects_with_permission": 18,
+  "service:api_list_objects": 15,
+  "service:list_objects_with_permission": 18,
+  "servicetemplate:api_list_objects": 12,
+  "servicetemplate:list_objects_with_permission": 17,
+  "vlan:api_list_objects": 14,
+  "vlan:list_objects_with_permission": 21,
+  "vlangroup:api_list_objects": 12,
+  "vlangroup:list_objects_with_permission": 22,
   "vlantranslationpolicy:api_list_objects": 12,
-  "vlantranslationpolicy:list_objects_with_permission": 20,
+  "vlantranslationpolicy:list_objects_with_permission": 17,
   "vlantranslationrule:api_list_objects": 12,
-  "vlantranslationrule:list_objects_with_permission": 21,
-  "vrf:api_list_objects": 15,
-  "vrf:list_objects_with_permission": 20
+  "vlantranslationrule:list_objects_with_permission": 18,
+  "vrf:api_list_objects": 14,
+  "vrf:list_objects_with_permission": 17
 }

+ 12 - 12
netbox/tenancy/tests/query_counts.json

@@ -1,14 +1,14 @@
 {
-  "contact:api_list_objects": 14,
-  "contact:list_objects_with_permission": 21,
-  "contactassignment:api_list_objects": 17,
-  "contactassignment:list_objects_with_permission": 25,
-  "contactgroup:api_list_objects": 14,
-  "contactgroup:list_objects_with_permission": 20,
-  "contactrole:api_list_objects": 13,
-  "contactrole:list_objects_with_permission": 20,
-  "tenant:api_list_objects": 14,
-  "tenant:list_objects_with_permission": 21,
-  "tenantgroup:api_list_objects": 14,
-  "tenantgroup:list_objects_with_permission": 20
+  "contact:api_list_objects": 13,
+  "contact:list_objects_with_permission": 18,
+  "contactassignment:api_list_objects": 16,
+  "contactassignment:list_objects_with_permission": 22,
+  "contactgroup:api_list_objects": 13,
+  "contactgroup:list_objects_with_permission": 17,
+  "contactrole:api_list_objects": 12,
+  "contactrole:list_objects_with_permission": 17,
+  "tenant:api_list_objects": 13,
+  "tenant:list_objects_with_permission": 18,
+  "tenantgroup:api_list_objects": 13,
+  "tenantgroup:list_objects_with_permission": 17
 }

+ 5 - 5
netbox/users/tests/query_counts.json

@@ -1,14 +1,14 @@
 {
   "group:api_list_objects": 10,
-  "group:list_objects_with_permission": 17,
+  "group:list_objects_with_permission": 16,
   "objectpermission:api_list_objects": 14,
-  "objectpermission:list_objects_with_permission": 18,
+  "objectpermission:list_objects_with_permission": 17,
   "owner:api_list_objects": 11,
-  "owner:list_objects_with_permission": 19,
+  "owner:list_objects_with_permission": 18,
   "ownergroup:api_list_objects": 9,
-  "ownergroup:list_objects_with_permission": 17,
+  "ownergroup:list_objects_with_permission": 16,
   "token:api_list_objects": 10,
   "token:list_objects_with_permission": 17,
   "user:api_list_objects": 12,
-  "user:list_objects_with_permission": 17
+  "user:list_objects_with_permission": 16
 }

+ 14 - 14
netbox/virtualization/tests/query_counts.json

@@ -1,16 +1,16 @@
 {
-  "cluster:api_list_objects": 16,
-  "cluster:list_objects_with_permission": 22,
-  "clustergroup:api_list_objects": 13,
-  "clustergroup:list_objects_with_permission": 20,
-  "clustertype:api_list_objects": 13,
-  "clustertype:list_objects_with_permission": 20,
-  "virtualdisk:api_list_objects": 14,
-  "virtualdisk:list_objects_with_permission": 21,
-  "virtualmachine:api_list_objects": 18,
-  "virtualmachine:list_objects_with_permission": 24,
-  "virtualmachinetype:api_list_objects": 14,
-  "virtualmachinetype:list_objects_with_permission": 21,
-  "vminterface:api_list_objects": 19,
-  "vminterface:list_objects_with_permission": 21
+  "cluster:api_list_objects": 15,
+  "cluster:list_objects_with_permission": 19,
+  "clustergroup:api_list_objects": 12,
+  "clustergroup:list_objects_with_permission": 17,
+  "clustertype:api_list_objects": 12,
+  "clustertype:list_objects_with_permission": 17,
+  "virtualdisk:api_list_objects": 13,
+  "virtualdisk:list_objects_with_permission": 18,
+  "virtualmachine:api_list_objects": 17,
+  "virtualmachine:list_objects_with_permission": 21,
+  "virtualmachinetype:api_list_objects": 13,
+  "virtualmachinetype:list_objects_with_permission": 18,
+  "vminterface:api_list_objects": 18,
+  "vminterface:list_objects_with_permission": 18
 }

+ 20 - 20
netbox/vpn/tests/query_counts.json

@@ -1,22 +1,22 @@
 {
-  "ikepolicy:api_list_objects": 14,
-  "ikepolicy:list_objects_with_permission": 21,
-  "ikeproposal:api_list_objects": 13,
-  "ikeproposal:list_objects_with_permission": 20,
-  "ipsecpolicy:api_list_objects": 14,
-  "ipsecpolicy:list_objects_with_permission": 21,
-  "ipsecprofile:api_list_objects": 15,
-  "ipsecprofile:list_objects_with_permission": 22,
-  "ipsecproposal:api_list_objects": 13,
-  "ipsecproposal:list_objects_with_permission": 20,
-  "l2vpn:api_list_objects": 15,
-  "l2vpn:list_objects_with_permission": 20,
-  "l2vpntermination:api_list_objects": 16,
-  "l2vpntermination:list_objects_with_permission": 25,
-  "tunnel:api_list_objects": 14,
-  "tunnel:list_objects_with_permission": 21,
-  "tunnelgroup:api_list_objects": 13,
-  "tunnelgroup:list_objects_with_permission": 20,
-  "tunneltermination:api_list_objects": 18,
-  "tunneltermination:list_objects_with_permission": 28
+  "ikepolicy:api_list_objects": 13,
+  "ikepolicy:list_objects_with_permission": 18,
+  "ikeproposal:api_list_objects": 12,
+  "ikeproposal:list_objects_with_permission": 17,
+  "ipsecpolicy:api_list_objects": 13,
+  "ipsecpolicy:list_objects_with_permission": 18,
+  "ipsecprofile:api_list_objects": 14,
+  "ipsecprofile:list_objects_with_permission": 19,
+  "ipsecproposal:api_list_objects": 12,
+  "ipsecproposal:list_objects_with_permission": 17,
+  "l2vpn:api_list_objects": 14,
+  "l2vpn:list_objects_with_permission": 17,
+  "l2vpntermination:api_list_objects": 15,
+  "l2vpntermination:list_objects_with_permission": 22,
+  "tunnel:api_list_objects": 13,
+  "tunnel:list_objects_with_permission": 18,
+  "tunnelgroup:api_list_objects": 12,
+  "tunnelgroup:list_objects_with_permission": 17,
+  "tunneltermination:api_list_objects": 17,
+  "tunneltermination:list_objects_with_permission": 25
 }

+ 6 - 6
netbox/wireless/tests/query_counts.json

@@ -1,8 +1,8 @@
 {
-  "wirelesslan:api_list_objects": 13,
-  "wirelesslan:list_objects_with_permission": 21,
-  "wirelesslangroup:api_list_objects": 13,
-  "wirelesslangroup:list_objects_with_permission": 21,
-  "wirelesslink:api_list_objects": 18,
-  "wirelesslink:list_objects_with_permission": 24
+  "wirelesslan:api_list_objects": 12,
+  "wirelesslan:list_objects_with_permission": 18,
+  "wirelesslangroup:api_list_objects": 12,
+  "wirelesslangroup:list_objects_with_permission": 18,
+  "wirelesslink:api_list_objects": 17,
+  "wirelesslink:list_objects_with_permission": 21
 }