1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #6138: Add an 'empty' filter modifier for character fields

This commit is contained in:
jeremystretch
2021-07-01 15:17:46 -04:00
parent add95292ce
commit 76a6119584
6 changed files with 45 additions and 23 deletions

View File

@ -4,6 +4,7 @@
### Enhancements ### Enhancements
* [#6138](https://github.com/netbox-community/netbox/issues/6138) - Add an `empty` filter modifier for character fields
* [#6620](https://github.com/netbox-community/netbox/issues/6620) - Show assigned VMs count under device role view * [#6620](https://github.com/netbox-community/netbox/issues/6620) - Show assigned VMs count under device role view
* [#6666](https://github.com/netbox-community/netbox/issues/6666) - Show management-only status under interface detail view * [#6666](https://github.com/netbox-community/netbox/issues/6666) - Show management-only status under interface detail view
* [#6667](https://github.com/netbox-community/netbox/issues/6667) - Display VM memory as GB/TB as appropriate * [#6667](https://github.com/netbox-community/netbox/issues/6667) - Display VM memory as GB/TB as appropriate

View File

@ -61,25 +61,30 @@ These lookup expressions can be applied by adding a suffix to the desired field'
Numeric based fields (ASN, VLAN ID, etc) support these lookup expressions: Numeric based fields (ASN, VLAN ID, etc) support these lookup expressions:
- `n` - not equal to (negation) | Filter | Description |
- `lt` - less than |--------|-------------|
- `lte` - less than or equal | `n` | Not equal to |
- `gt` - greater than | `lt` | Less than |
- `gte` - greater than or equal | `lte` | Less than or equal to |
| `gt` | Greater than |
| `gte` | Greater than or equal to |
### String Fields ### String Fields
String based (char) fields (Name, Address, etc) support these lookup expressions: String based (char) fields (Name, Address, etc) support these lookup expressions:
- `n` - not equal to (negation) | Filter | Description |
- `ic` - case insensitive contains |--------|-------------|
- `nic` - negated case insensitive contains | `n` | Not equal to |
- `isw` - case insensitive starts with | `ic` | Contains (case-insensitive) |
- `nisw` - negated case insensitive starts with | `nic` | Does not contain (case-insensitive) |
- `iew` - case insensitive ends with | `isw` | Starts with (case-insensitive) |
- `niew` - negated case insensitive ends with | `nisw` | Does not start with (case-insensitive) |
- `ie` - case insensitive exact match | `iew` | Ends with (case-insensitive) |
- `nie` - negated case insensitive exact match | `niew` | Does not end with (case-insensitive) |
| `ie` | Exact match (case-insensitive) |
| `nie` | Inverse exact match (case-insensitive) |
| `empty` | Is empty (boolean) |
### Foreign Keys & Other Fields ### Foreign Keys & Other Fields

View File

@ -5,4 +5,5 @@ class ExtrasConfig(AppConfig):
name = "extras" name = "extras"
def ready(self): def ready(self):
import extras.lookups
import extras.signals import extras.signals

17
netbox/extras/lookups.py Normal file
View File

@ -0,0 +1,17 @@
from django.db.models import CharField, Lookup
class Empty(Lookup):
"""
Filter on whether a string is empty.
"""
lookup_name = 'empty'
def as_sql(self, qn, connection):
lhs, lhs_params = self.process_lhs(qn, connection)
rhs, rhs_params = self.process_rhs(qn, connection)
params = lhs_params + rhs_params
return 'CAST(LENGTH(%s) AS BOOLEAN) != %s' % (lhs, rhs), params
CharField.register_lookup(Empty)

View File

@ -89,13 +89,13 @@ class BaseFilterSet(django_filters.FilterSet):
filters.MultiValueNumberFilter, filters.MultiValueNumberFilter,
filters.MultiValueTimeFilter filters.MultiValueTimeFilter
)): )):
lookup_map = FILTER_NUMERIC_BASED_LOOKUP_MAP return FILTER_NUMERIC_BASED_LOOKUP_MAP
elif isinstance(existing_filter, ( elif isinstance(existing_filter, (
filters.TreeNodeMultipleChoiceFilter, filters.TreeNodeMultipleChoiceFilter,
)): )):
# TreeNodeMultipleChoiceFilter only support negation but must maintain the `in` lookup expression # TreeNodeMultipleChoiceFilter only support negation but must maintain the `in` lookup expression
lookup_map = FILTER_TREENODE_NEGATION_LOOKUP_MAP return FILTER_TREENODE_NEGATION_LOOKUP_MAP
elif isinstance(existing_filter, ( elif isinstance(existing_filter, (
django_filters.ModelChoiceFilter, django_filters.ModelChoiceFilter,
@ -103,7 +103,7 @@ class BaseFilterSet(django_filters.FilterSet):
TagFilter TagFilter
)) or existing_filter.extra.get('choices'): )) or existing_filter.extra.get('choices'):
# These filter types support only negation # These filter types support only negation
lookup_map = FILTER_NEGATION_LOOKUP_MAP return FILTER_NEGATION_LOOKUP_MAP
elif isinstance(existing_filter, ( elif isinstance(existing_filter, (
django_filters.filters.CharFilter, django_filters.filters.CharFilter,
@ -111,12 +111,9 @@ class BaseFilterSet(django_filters.FilterSet):
filters.MultiValueCharFilter, filters.MultiValueCharFilter,
filters.MultiValueMACAddressFilter filters.MultiValueMACAddressFilter
)): )):
lookup_map = FILTER_CHAR_BASED_LOOKUP_MAP return FILTER_CHAR_BASED_LOOKUP_MAP
else: return None
lookup_map = None
return lookup_map
@classmethod @classmethod
def get_filters(cls): def get_filters(cls):

View File

@ -11,7 +11,8 @@ FILTER_CHAR_BASED_LOOKUP_MAP = dict(
isw='istartswith', isw='istartswith',
nisw='istartswith', nisw='istartswith',
ie='iexact', ie='iexact',
nie='iexact' nie='iexact',
empty='empty',
) )
FILTER_NUMERIC_BASED_LOOKUP_MAP = dict( FILTER_NUMERIC_BASED_LOOKUP_MAP = dict(