optimize query

This commit is contained in:
kobayashi 2020-01-12 16:44:15 -05:00
parent 2e9f21e222
commit e3aacb183b
3 changed files with 31 additions and 17 deletions

View File

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

View File

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

View File

@ -100,23 +100,40 @@ class NetHost(Lookup):
return 'HOST(%s) = %s' % (lhs, rhs), params return 'HOST(%s) = %s' % (lhs, rhs), params
class NetHostIn(Lookup): class NetIn(Lookup):
lookup_name = 'net_host_in' lookup_name = 'net_in'
def as_sql(self, qn, connection): def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection) lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection) rhs, rhs_params = self.process_rhs(qn, connection)
in_elements = ['HOST(%s) IN (' % lhs] with_mask, without_mask = [], []
params = [] for address in rhs_params[0]:
for offset in range(0, len(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: if offset > 0:
in_elements.append(', ') clause_elements.append(', ')
params.extend(lhs_params) clause_elements.append('%s')
sqls_params = rhs_params[0][offset] clause_elements.append(')')
in_elements.append(rhs) return ''.join(clause_elements)
params.append(sqls_params)
in_elements.append(')')
return ''.join(in_elements), params
class NetHostContained(Lookup): class NetHostContained(Lookup):