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
* [#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
* [#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

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:
- `n` - not equal to (negation)
- `lt` - less than
- `lte` - less than or equal
- `gt` - greater than
- `gte` - greater than or equal
| Filter | Description |
|--------|-------------|
| `n` | Not equal to |
| `lt` | Less than |
| `lte` | Less than or equal to |
| `gt` | Greater than |
| `gte` | Greater than or equal to |
### String Fields
String based (char) fields (Name, Address, etc) support these lookup expressions:
- `n` - not equal to (negation)
- `ic` - case insensitive contains
- `nic` - negated case insensitive contains
- `isw` - case insensitive starts with
- `nisw` - negated case insensitive starts with
- `iew` - case insensitive ends with
- `niew` - negated case insensitive ends with
- `ie` - case insensitive exact match
- `nie` - negated case insensitive exact match
| Filter | Description |
|--------|-------------|
| `n` | Not equal to |
| `ic` | Contains (case-insensitive) |
| `nic` | Does not contain (case-insensitive) |
| `isw` | Starts with (case-insensitive) |
| `nisw` | Does not start with (case-insensitive) |
| `iew` | Ends with (case-insensitive) |
| `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

View File

@ -5,4 +5,5 @@ class ExtrasConfig(AppConfig):
name = "extras"
def ready(self):
import extras.lookups
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.MultiValueTimeFilter
)):
lookup_map = FILTER_NUMERIC_BASED_LOOKUP_MAP
return FILTER_NUMERIC_BASED_LOOKUP_MAP
elif isinstance(existing_filter, (
filters.TreeNodeMultipleChoiceFilter,
)):
# 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, (
django_filters.ModelChoiceFilter,
@ -103,7 +103,7 @@ class BaseFilterSet(django_filters.FilterSet):
TagFilter
)) or existing_filter.extra.get('choices'):
# These filter types support only negation
lookup_map = FILTER_NEGATION_LOOKUP_MAP
return FILTER_NEGATION_LOOKUP_MAP
elif isinstance(existing_filter, (
django_filters.filters.CharFilter,
@ -111,12 +111,9 @@ class BaseFilterSet(django_filters.FilterSet):
filters.MultiValueCharFilter,
filters.MultiValueMACAddressFilter
)):
lookup_map = FILTER_CHAR_BASED_LOOKUP_MAP
return FILTER_CHAR_BASED_LOOKUP_MAP
else:
lookup_map = None
return lookup_map
return None
@classmethod
def get_filters(cls):

View File

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