mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #13585: Introduce 'empty' lookup for numeric value filters
This commit is contained in:
@ -61,13 +61,14 @@ 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:
|
||||||
|
|
||||||
| Filter | Description |
|
| Filter | Description |
|
||||||
|--------|-------------|
|
|---------|--------------------------|
|
||||||
| `n` | Not equal to |
|
| `n` | Not equal to |
|
||||||
| `lt` | Less than |
|
| `lt` | Less than |
|
||||||
| `lte` | Less than or equal to |
|
| `lte` | Less than or equal to |
|
||||||
| `gt` | Greater than |
|
| `gt` | Greater than |
|
||||||
| `gte` | Greater than or equal to |
|
| `gte` | Greater than or equal to |
|
||||||
|
| `empty` | Is empty/null (boolean) |
|
||||||
|
|
||||||
Here is an example of a numeric field lookup expression that will return all VLANs with a VLAN ID greater than 900:
|
Here is an example of a numeric field lookup expression that will return all VLANs with a VLAN ID greater than 900:
|
||||||
|
|
||||||
@ -79,18 +80,18 @@ GET /api/ipam/vlans/?vid__gt=900
|
|||||||
|
|
||||||
String based (char) fields (Name, Address, etc) support these lookup expressions:
|
String based (char) fields (Name, Address, etc) support these lookup expressions:
|
||||||
|
|
||||||
| Filter | Description |
|
| Filter | Description |
|
||||||
|--------|-------------|
|
|---------|----------------------------------------|
|
||||||
| `n` | Not equal to |
|
| `n` | Not equal to |
|
||||||
| `ic` | Contains (case-insensitive) |
|
| `ic` | Contains (case-insensitive) |
|
||||||
| `nic` | Does not contain (case-insensitive) |
|
| `nic` | Does not contain (case-insensitive) |
|
||||||
| `isw` | Starts with (case-insensitive) |
|
| `isw` | Starts with (case-insensitive) |
|
||||||
| `nisw` | Does not start with (case-insensitive) |
|
| `nisw` | Does not start with (case-insensitive) |
|
||||||
| `iew` | Ends with (case-insensitive) |
|
| `iew` | Ends with (case-insensitive) |
|
||||||
| `niew` | Does not end with (case-insensitive) |
|
| `niew` | Does not end with (case-insensitive) |
|
||||||
| `ie` | Exact match (case-insensitive) |
|
| `ie` | Exact match (case-insensitive) |
|
||||||
| `nie` | Inverse exact match (case-insensitive) |
|
| `nie` | Inverse exact match (case-insensitive) |
|
||||||
| `empty` | Is empty (boolean) |
|
| `empty` | Is empty/null (boolean) |
|
||||||
|
|
||||||
Here is an example of a lookup expression on a string field that will return all devices with `switch` in the name:
|
Here is an example of a lookup expression on a string field that will return all devices with `switch` in the name:
|
||||||
|
|
||||||
|
@ -20,7 +20,8 @@ FILTER_NUMERIC_BASED_LOOKUP_MAP = dict(
|
|||||||
lte='lte',
|
lte='lte',
|
||||||
lt='lt',
|
lt='lt',
|
||||||
gte='gte',
|
gte='gte',
|
||||||
gt='gt'
|
gt='gt',
|
||||||
|
empty='isnull',
|
||||||
)
|
)
|
||||||
|
|
||||||
FILTER_NEGATION_LOOKUP_MAP = dict(
|
FILTER_NEGATION_LOOKUP_MAP = dict(
|
||||||
|
@ -86,6 +86,10 @@ class DummyModel(models.Model):
|
|||||||
charfield = models.CharField(
|
charfield = models.CharField(
|
||||||
max_length=10
|
max_length=10
|
||||||
)
|
)
|
||||||
|
numberfield = models.IntegerField(
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
choicefield = models.IntegerField(
|
choicefield = models.IntegerField(
|
||||||
choices=(('A', 1), ('B', 2), ('C', 3))
|
choices=(('A', 1), ('B', 2), ('C', 3))
|
||||||
)
|
)
|
||||||
@ -108,6 +112,7 @@ class BaseFilterSetTest(TestCase):
|
|||||||
"""
|
"""
|
||||||
class DummyFilterSet(BaseFilterSet):
|
class DummyFilterSet(BaseFilterSet):
|
||||||
charfield = django_filters.CharFilter()
|
charfield = django_filters.CharFilter()
|
||||||
|
numberfield = django_filters.NumberFilter()
|
||||||
macaddressfield = MACAddressFilter()
|
macaddressfield = MACAddressFilter()
|
||||||
modelchoicefield = django_filters.ModelChoiceFilter(
|
modelchoicefield = django_filters.ModelChoiceFilter(
|
||||||
field_name='integerfield', # We're pretending this is a ForeignKey field
|
field_name='integerfield', # We're pretending this is a ForeignKey field
|
||||||
@ -132,6 +137,7 @@ class BaseFilterSetTest(TestCase):
|
|||||||
model = DummyModel
|
model = DummyModel
|
||||||
fields = (
|
fields = (
|
||||||
'charfield',
|
'charfield',
|
||||||
|
'numberfield',
|
||||||
'choicefield',
|
'choicefield',
|
||||||
'datefield',
|
'datefield',
|
||||||
'datetimefield',
|
'datetimefield',
|
||||||
@ -171,6 +177,25 @@ class BaseFilterSetTest(TestCase):
|
|||||||
self.assertEqual(self.filters['charfield__iew'].exclude, False)
|
self.assertEqual(self.filters['charfield__iew'].exclude, False)
|
||||||
self.assertEqual(self.filters['charfield__niew'].lookup_expr, 'iendswith')
|
self.assertEqual(self.filters['charfield__niew'].lookup_expr, 'iendswith')
|
||||||
self.assertEqual(self.filters['charfield__niew'].exclude, True)
|
self.assertEqual(self.filters['charfield__niew'].exclude, True)
|
||||||
|
self.assertEqual(self.filters['charfield__empty'].lookup_expr, 'empty')
|
||||||
|
self.assertEqual(self.filters['charfield__empty'].exclude, False)
|
||||||
|
|
||||||
|
def test_number_filter(self):
|
||||||
|
self.assertIsInstance(self.filters['numberfield'], django_filters.NumberFilter)
|
||||||
|
self.assertEqual(self.filters['numberfield'].lookup_expr, 'exact')
|
||||||
|
self.assertEqual(self.filters['numberfield'].exclude, False)
|
||||||
|
self.assertEqual(self.filters['numberfield__n'].lookup_expr, 'exact')
|
||||||
|
self.assertEqual(self.filters['numberfield__n'].exclude, True)
|
||||||
|
self.assertEqual(self.filters['numberfield__lt'].lookup_expr, 'lt')
|
||||||
|
self.assertEqual(self.filters['numberfield__lt'].exclude, False)
|
||||||
|
self.assertEqual(self.filters['numberfield__lte'].lookup_expr, 'lte')
|
||||||
|
self.assertEqual(self.filters['numberfield__lte'].exclude, False)
|
||||||
|
self.assertEqual(self.filters['numberfield__gt'].lookup_expr, 'gt')
|
||||||
|
self.assertEqual(self.filters['numberfield__gt'].exclude, False)
|
||||||
|
self.assertEqual(self.filters['numberfield__gte'].lookup_expr, 'gte')
|
||||||
|
self.assertEqual(self.filters['numberfield__gte'].exclude, False)
|
||||||
|
self.assertEqual(self.filters['numberfield__empty'].lookup_expr, 'isnull')
|
||||||
|
self.assertEqual(self.filters['numberfield__empty'].exclude, False)
|
||||||
|
|
||||||
def test_mac_address_filter(self):
|
def test_mac_address_filter(self):
|
||||||
self.assertIsInstance(self.filters['macaddressfield'], MACAddressFilter)
|
self.assertIsInstance(self.filters['macaddressfield'], MACAddressFilter)
|
||||||
|
Reference in New Issue
Block a user