Jelajahi Sumber

optimize query

kobayashi 6 tahun lalu
induk
melakukan
e3aacb183b
3 mengubah file dengan 31 tambahan dan 17 penghapusan
  1. 1 1
      netbox/ipam/fields.py
  2. 1 4
      netbox/ipam/filters.py
  3. 29 12
      netbox/ipam/lookups.py

+ 1 - 1
netbox/ipam/fields.py

@@ -95,6 +95,6 @@ IPAddressField.register_lookup(lookups.NetContainedOrEqual)
 IPAddressField.register_lookup(lookups.NetContains)
 IPAddressField.register_lookup(lookups.NetContainsOrEquals)
 IPAddressField.register_lookup(lookups.NetHost)
-IPAddressField.register_lookup(lookups.NetHostIn)
+IPAddressField.register_lookup(lookups.NetIn)
 IPAddressField.register_lookup(lookups.NetHostContained)
 IPAddressField.register_lookup(lookups.NetMaskLength)

+ 1 - 4
netbox/ipam/filters.py

@@ -372,10 +372,7 @@ class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet, CreatedUpdatedFilt
 
     def filter_address(self, queryset, name, value):
         try:
-            return queryset.filter(
-                Q(address__in=value) |
-                Q(address__net_host_in=value)
-            )
+            return queryset.filter(address__net_in=value)
         except ValidationError:
             return queryset.none()
 

+ 29 - 12
netbox/ipam/lookups.py

@@ -100,23 +100,40 @@ class NetHost(Lookup):
         return 'HOST(%s) = %s' % (lhs, rhs), params
 
 
-class NetHostIn(Lookup):
-    lookup_name = 'net_host_in'
+class NetIn(Lookup):
+    lookup_name = 'net_in'
 
     def as_sql(self, qn, connection):
         lhs, lhs_params = self.process_lhs(qn, connection)
         rhs, rhs_params = self.process_rhs(qn, connection)
-        in_elements = ['HOST(%s) IN (' % lhs]
-        params = []
-        for offset in range(0, len(rhs_params[0])):
+        with_mask, without_mask = [], []
+        for address in rhs_params[0]:
+            if '/' in address:
+                with_mask.append(address)
+            else:
+                without_mask.append(address)
+
+        address_in_clause = self.create_in_clause('{} IN ('.format(lhs), len(with_mask))
+        host_in_clause = self.create_in_clause('HOST({}) IN ('.format(lhs), len(without_mask))
+
+        if with_mask and not without_mask:
+            return address_in_clause, with_mask
+        elif not with_mask and without_mask:
+            return host_in_clause, without_mask
+
+        in_clause = '({}) OR ({})'.format(address_in_clause, host_in_clause)
+        with_mask.extend(without_mask)
+        return in_clause, with_mask
+
+    @staticmethod
+    def create_in_clause(clause_part, max_size):
+        clause_elements = [clause_part]
+        for offset in range(0, max_size):
             if offset > 0:
-                in_elements.append(', ')
-            params.extend(lhs_params)
-            sqls_params = rhs_params[0][offset]
-            in_elements.append(rhs)
-            params.append(sqls_params)
-        in_elements.append(')')
-        return ''.join(in_elements), params
+                clause_elements.append(', ')
+            clause_elements.append('%s')
+        clause_elements.append(')')
+        return ''.join(clause_elements)
 
 
 class NetHostContained(Lookup):