Add support for filtering empty custom fields via the ReST API via the __empty keyword #8089

Closed
opened 2025-12-29 20:32:15 +01:00 by adam · 9 comments
Owner

Originally created by @tbotnz on GitHub (May 19, 2023).

NetBox version

3.5.1

Feature type

New functionality

Proposed functionality

support __empty string on custom field filtering via the API

Use case

filter via the API whether the custom field is empty or not

Database changes

none

External dependencies

none

Originally created by @tbotnz on GitHub (May 19, 2023). ### NetBox version 3.5.1 ### Feature type New functionality ### Proposed functionality support `__empty` string on custom field filtering via the API ### Use case filter via the API whether the custom field is empty or not ### Database changes none ### External dependencies none
adam added the type: featurestatus: needs ownerpending closure labels 2025-12-29 20:32:15 +01:00
adam closed this issue 2025-12-29 20:32:16 +01:00
Author
Owner

@jsenecal commented on GitHub (May 19, 2023):

Just to be clear, you know that using the filter cf_customfield=null works, right ?

I however agree that the boolean filter __empty is missing there and should be implemented.

@jsenecal commented on GitHub (May 19, 2023): Just to be clear, you know that using the filter `cf_customfield=null` works, right ? I however agree that the boolean filter `__empty` is missing there and should be implemented.
Author
Owner

@tbotnz commented on GitHub (May 19, 2023):

@jsenecal did try this however it returns a http 500 status

@tbotnz commented on GitHub (May 19, 2023): @jsenecal did try this however it returns a http 500 status
Author
Owner

@jsenecal commented on GitHub (May 19, 2023):

Take a look at this: https://demo.netbox.dev/api/tenancy/tenants/?cf_cust_id=null

@jsenecal commented on GitHub (May 19, 2023): Take a look at this: https://demo.netbox.dev/api/tenancy/tenants/?cf_cust_id=null
Author
Owner

@tbotnz commented on GitHub (May 19, 2023):

thanks but as i mentioned before it does not work.

stack trace for that one below

Internal Server Error: /api/dcim/devices/ Traceback (most recent call last): File "/opt/netbox/venv/lib64/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view return self.dispatch(request, *args, **kwargs) File "/opt/netbox-3.4.1/netbox/netbox/api/viewsets/__init__.py", line 118, in dispatch return super().dispatch(request, *args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs) File "/opt/netbox-3.4.1/netbox/netbox/api/viewsets/__init__.py", line 149, in list return super().list(request, *args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/mixins.py", line 38, in list queryset = self.filter_queryset(self.get_queryset()) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/generics.py", line 150, in filter_queryset queryset = backend().filter_queryset(self.request, queryset, self) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/rest_framework/backends.py", line 74, in filter_queryset return filterset.qs File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filterset.py", line 230, in qs qs = self.filter_queryset(qs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filterset.py", line 213, in filter_queryset queryset = self.filters[name].filter(queryset, value) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filters.py", line 263, in filter qs = self.get_method(qs)(q) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1421, in filter return self._filter_or_exclude(False, args, kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1439, in _filter_or_exclude clone._filter_or_exclude_inplace(negate, args, kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1446, in _filter_or_exclude_inplace self._query.add_q(Q(*args, **kwargs)) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1532, in add_q clause, _ = self._add_q(q_object, self.used_aliases) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1562, in _add_q child_clause, needed_inner = self.build_filter( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1388, in build_filter return self._add_q( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1562, in _add_q child_clause, needed_inner = self.build_filter( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1478, in build_filter condition = self.build_lookup(lookups, col, value) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1308, in build_lookup raise ValueError("Cannot use None as a query value") ValueError: Cannot use None as a query value

@tbotnz commented on GitHub (May 19, 2023): thanks but as i mentioned before it does not work. stack trace for that one below `Internal Server Error: /api/dcim/devices/ Traceback (most recent call last): File "/opt/netbox/venv/lib64/python3.9/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view return view_func(*args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/viewsets.py", line 125, in view return self.dispatch(request, *args, **kwargs) File "/opt/netbox-3.4.1/netbox/netbox/api/viewsets/__init__.py", line 118, in dispatch return super().dispatch(request, *args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch response = self.handle_exception(exc) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception self.raise_uncaught_exception(exc) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception raise exc File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch response = handler(request, *args, **kwargs) File "/opt/netbox-3.4.1/netbox/netbox/api/viewsets/__init__.py", line 149, in list return super().list(request, *args, **kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/mixins.py", line 38, in list queryset = self.filter_queryset(self.get_queryset()) File "/opt/netbox/venv/lib64/python3.9/site-packages/rest_framework/generics.py", line 150, in filter_queryset queryset = backend().filter_queryset(self.request, queryset, self) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/rest_framework/backends.py", line 74, in filter_queryset return filterset.qs File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filterset.py", line 230, in qs qs = self.filter_queryset(qs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filterset.py", line 213, in filter_queryset queryset = self.filters[name].filter(queryset, value) File "/opt/netbox/venv/lib64/python3.9/site-packages/django_filters/filters.py", line 263, in filter qs = self.get_method(qs)(q) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1421, in filter return self._filter_or_exclude(False, args, kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1439, in _filter_or_exclude clone._filter_or_exclude_inplace(negate, args, kwargs) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/query.py", line 1446, in _filter_or_exclude_inplace self._query.add_q(Q(*args, **kwargs)) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1532, in add_q clause, _ = self._add_q(q_object, self.used_aliases) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1562, in _add_q child_clause, needed_inner = self.build_filter( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1388, in build_filter return self._add_q( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1562, in _add_q child_clause, needed_inner = self.build_filter( File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1478, in build_filter condition = self.build_lookup(lookups, col, value) File "/opt/netbox/venv/lib64/python3.9/site-packages/django/db/models/sql/query.py", line 1308, in build_lookup raise ValueError("Cannot use None as a query value") ValueError: Cannot use None as a query value`
Author
Owner

@jsenecal commented on GitHub (May 19, 2023):

What is your custom_field type ?

@jsenecal commented on GitHub (May 19, 2023): What is your custom_field type ?
Author
Owner

@tbotnz commented on GitHub (May 20, 2023):

its, text and filter logic set for loose ( for other reasons ), this is reproducible via the test instance
https://demo.netbox.dev/api/tenancy/tenants/?cf_cust_id=null

IMO the cf query api should adopt the __empty like the std fields as this is a better DX

@tbotnz commented on GitHub (May 20, 2023): its, text and filter logic set for loose ( for other reasons ), this is reproducible via the test instance https://demo.netbox.dev/api/tenancy/tenants/?cf_cust_id=null IMO the cf query api should adopt the __empty like the std fields as this is a better DX
Author
Owner

@jsenecal commented on GitHub (May 20, 2023):

Thank you for this clarification, the fact that it is completely crashing on "filter_logic": "loose" is another bug that should be considered.

@jsenecal commented on GitHub (May 20, 2023): Thank you for this clarification, the fact that it is completely crashing on `"filter_logic": "loose"` is another bug that should be considered.
Author
Owner

@github-actions[bot] commented on GitHub (Oct 11, 2023):

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. Do not attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our contributing guide.

@github-actions[bot] commented on GitHub (Oct 11, 2023): This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. NetBox is governed by a small group of core maintainers which means not all opened issues may receive direct feedback. **Do not** attempt to circumvent this process by "bumping" the issue; doing so will result in its immediate closure and you may be barred from participating in any future discussions. Please see our [contributing guide](https://github.com/netbox-community/netbox/blob/develop/CONTRIBUTING.md).
Author
Owner

@github-actions[bot] commented on GitHub (Nov 11, 2023):

This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.

@github-actions[bot] commented on GitHub (Nov 11, 2023): This issue has been automatically closed due to lack of activity. In an effort to reduce noise, please do not comment any further. Note that the core maintainers may elect to reopen this issue at a later date if deemed necessary.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#8089