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:
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
17
netbox/extras/lookups.py
Normal 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)
|
@ -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):
|
||||||
|
@ -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(
|
||||||
|
Reference in New Issue
Block a user