api custom_field filter not work with negation #9539

Closed
opened 2025-12-29 20:51:12 +01:00 by adam · 3 comments
Owner

Originally created by @davama on GitHub (Apr 25, 2024).

Deployment Type

Self-hosted

NetBox Version

v3.7.6

Python Version

3.11

Steps to Reproduce

I am trying to filter for custom fields that are not null or not a string. Saw this ticket but it is closed now.
Created the below cf for testing.

custom_fields
[
  {
    "id": 35,
    "url": "https://redacted/api/extras/custom-fields/35/",
    "display": "repoempty",
    "content_types": [
      "dcim.device"
    ],
    "type": {
      "value": "text",
      "label": "Text"
    },
    "object_type": null,
    "data_type": "string",
    "name": "repoempty",
    "label": "repoempty",
    "group_name": "",
    "description": "dummy cf - when default value is the literal string \"\"",
    "required": false,
    "search_weight": 1000,
    "filter_logic": {
      "value": "loose",
      "label": "Loose"
    },
    "ui_visible": {
      "value": "always",
      "label": "Always"
    },
    "ui_editable": {
      "value": "yes",
      "label": "Yes"
    },
    "is_cloneable": false,
    "default": "",
    "weight": 100,
    "validation_minimum": null,
    "validation_maximum": null,
    "validation_regex": "",
    "choice_set": null,
    "created": "2024-04-25T14:01:21.196733Z",
    "last_updated": "2024-04-25T14:01:21.196769Z"
  },
  {
    "id": 34,
    "url": "https://redacted/api/extras/custom-fields/34/",
    "display": "repoemptystring",
    "content_types": [
      "dcim.device"
    ],
    "type": {
      "value": "text",
      "label": "Text"
    },
    "object_type": null,
    "data_type": "string",
    "name": "repoemptystring",
    "label": "repoemptystring",
    "group_name": "",
    "description": "dummy cf - when default value is the literal string \"empty\"",
    "required": false,
    "search_weight": 1000,
    "filter_logic": {
      "value": "loose",
      "label": "Loose"
    },
    "ui_visible": {
      "value": "always",
      "label": "Always"
    },
    "ui_editable": {
      "value": "yes",
      "label": "Yes"
    },
    "is_cloneable": false,
    "default": "empty",
    "weight": 100,
    "validation_minimum": null,
    "validation_maximum": null,
    "validation_regex": "",
    "choice_set": null,
    "created": "2024-04-25T14:00:02.456419Z",
    "last_updated": "2024-04-25T14:00:02.456460Z"
  },
  {
    "id": 33,
    "url": "https://redacted/api/extras/custom-fields/33/",
    "display": "reponull",
    "content_types": [
      "dcim.device"
    ],
    "type": {
      "value": "text",
      "label": "Text"
    },
    "object_type": null,
    "data_type": "string",
    "name": "reponull",
    "label": "reponull",
    "group_name": "",
    "description": "dummy cf - when default value is null",
    "required": false,
    "search_weight": 1000,
    "filter_logic": {
      "value": "loose",
      "label": "Loose"
    },
    "ui_visible": {
      "value": "always",
      "label": "Always"
    },
    "ui_editable": {
      "value": "yes",
      "label": "Yes"
    },
    "is_cloneable": false,
    "default": null,
    "weight": 100,
    "validation_minimum": null,
    "validation_maximum": null,
    "validation_regex": "",
    "choice_set": null,
    "created": "2024-04-25T13:57:41.959924Z",
    "last_updated": "2024-04-25T13:57:41.959962Z"
  },
  {
    "id": 36,
    "url": "https://redacted/api/extras/custom-fields/36/",
    "display": "reponullstring",
    "content_types": [
      "dcim.device"
    ],
    "type": {
      "value": "text",
      "label": "Text"
    },
    "object_type": null,
    "data_type": "string",
    "name": "reponullstring",
    "label": "reponullstring",
    "group_name": "",
    "description": "dummy cf - when default value is the literal string \"null\"",
    "required": false,
    "search_weight": 1000,
    "filter_logic": {
      "value": "loose",
      "label": "Loose"
    },
    "ui_visible": {
      "value": "always",
      "label": "Always"
    },
    "ui_editable": {
      "value": "yes",
      "label": "Yes"
    },
    "is_cloneable": false,
    "default": "null",
    "weight": 100,
    "validation_minimum": null,
    "validation_maximum": null,
    "validation_regex": "",
    "choice_set": null,
    "created": "2024-04-25T14:03:07.790615Z",
    "last_updated": "2024-04-25T14:03:07.790651Z"
  }
]

The default values look like this on a device:

                "repoempty": "",
                "repoemptystring": "empty",
                "reponull": null,
                "reponullstring": "null",

The values I changed for one device:

                "repoempty": "data",
                "repoemptystring": "something",
                "reponull": null,
                "reponullstring": "null",

API calls that worked

/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty=data
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoemptystring=something  ( I know it's redundant)

The API calls that did not work. I would still get all my devices for X site.

/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty=
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty__nie=data
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoemptystring__nie=something
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponull__empty=false
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponull__empty=0
/api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponullstring=null (got ValueError `Cannot use None as a query value`)

If I'm doing something wrong, please let me know.

Any input is appreciated.

Thank you,
Dave

Expected Behavior

Since I change the cf values for one device I would expect to only get this device returned.

If I negate the filter, then I would expect all my devices for site X minus 1 to return.

Observed Behavior

The negation filter does not work for a string.

When the value is null, I also cannot filter either =null or !=null.

Originally created by @davama on GitHub (Apr 25, 2024). ### Deployment Type Self-hosted ### NetBox Version v3.7.6 ### Python Version 3.11 ### Steps to Reproduce I am trying to filter for custom fields that are not `null` or not a string. Saw this [ticket](https://github.com/netbox-community/netbox/issues/11538) but it is closed now. Created the below cf for testing. <details open> <summary>custom_fields</summary> <br> <pre> [ { "id": 35, "url": "https://redacted/api/extras/custom-fields/35/", "display": "repoempty", "content_types": [ "dcim.device" ], "type": { "value": "text", "label": "Text" }, "object_type": null, "data_type": "string", "name": "repoempty", "label": "repoempty", "group_name": "", "description": "dummy cf - when default value is the literal string \"\"", "required": false, "search_weight": 1000, "filter_logic": { "value": "loose", "label": "Loose" }, "ui_visible": { "value": "always", "label": "Always" }, "ui_editable": { "value": "yes", "label": "Yes" }, "is_cloneable": false, "default": "", "weight": 100, "validation_minimum": null, "validation_maximum": null, "validation_regex": "", "choice_set": null, "created": "2024-04-25T14:01:21.196733Z", "last_updated": "2024-04-25T14:01:21.196769Z" }, { "id": 34, "url": "https://redacted/api/extras/custom-fields/34/", "display": "repoemptystring", "content_types": [ "dcim.device" ], "type": { "value": "text", "label": "Text" }, "object_type": null, "data_type": "string", "name": "repoemptystring", "label": "repoemptystring", "group_name": "", "description": "dummy cf - when default value is the literal string \"empty\"", "required": false, "search_weight": 1000, "filter_logic": { "value": "loose", "label": "Loose" }, "ui_visible": { "value": "always", "label": "Always" }, "ui_editable": { "value": "yes", "label": "Yes" }, "is_cloneable": false, "default": "empty", "weight": 100, "validation_minimum": null, "validation_maximum": null, "validation_regex": "", "choice_set": null, "created": "2024-04-25T14:00:02.456419Z", "last_updated": "2024-04-25T14:00:02.456460Z" }, { "id": 33, "url": "https://redacted/api/extras/custom-fields/33/", "display": "reponull", "content_types": [ "dcim.device" ], "type": { "value": "text", "label": "Text" }, "object_type": null, "data_type": "string", "name": "reponull", "label": "reponull", "group_name": "", "description": "dummy cf - when default value is null", "required": false, "search_weight": 1000, "filter_logic": { "value": "loose", "label": "Loose" }, "ui_visible": { "value": "always", "label": "Always" }, "ui_editable": { "value": "yes", "label": "Yes" }, "is_cloneable": false, "default": null, "weight": 100, "validation_minimum": null, "validation_maximum": null, "validation_regex": "", "choice_set": null, "created": "2024-04-25T13:57:41.959924Z", "last_updated": "2024-04-25T13:57:41.959962Z" }, { "id": 36, "url": "https://redacted/api/extras/custom-fields/36/", "display": "reponullstring", "content_types": [ "dcim.device" ], "type": { "value": "text", "label": "Text" }, "object_type": null, "data_type": "string", "name": "reponullstring", "label": "reponullstring", "group_name": "", "description": "dummy cf - when default value is the literal string \"null\"", "required": false, "search_weight": 1000, "filter_logic": { "value": "loose", "label": "Loose" }, "ui_visible": { "value": "always", "label": "Always" }, "ui_editable": { "value": "yes", "label": "Yes" }, "is_cloneable": false, "default": "null", "weight": 100, "validation_minimum": null, "validation_maximum": null, "validation_regex": "", "choice_set": null, "created": "2024-04-25T14:03:07.790615Z", "last_updated": "2024-04-25T14:03:07.790651Z" } ] </pre> </details> The default values look like this on a device: ``` "repoempty": "", "repoemptystring": "empty", "reponull": null, "reponullstring": "null", ``` The values I changed for one device: ``` "repoempty": "data", "repoemptystring": "something", "reponull": null, "reponullstring": "null", ``` API calls that worked ``` /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty=data /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoemptystring=something ( I know it's redundant) ``` The API calls that did not work. I would still get all my devices for X site. ``` /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty= /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoempty__nie=data /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_repoemptystring__nie=something /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponull__empty=false /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponull__empty=0 /api/dcim/devices/?exclude=config_context&limit=0&site=usa-ht&cf_reponullstring=null (got ValueError `Cannot use None as a query value`) ``` If I'm doing something wrong, please let me know. Any input is appreciated. Thank you, Dave ### Expected Behavior Since I change the cf values for one device I would expect to only get this device returned. If I negate the filter, then I would expect all my devices for site X minus 1 to return. ### Observed Behavior The negation filter does not work for a string. When the value is `null`, I also cannot filter either `=null` or `!=null`.
adam added the type: bugstatus: revisions needed labels 2025-12-29 20:51:12 +01:00
adam closed this issue 2025-12-29 20:51:12 +01:00
Author
Owner

@arthanson commented on GitHub (Apr 26, 2024):

@davama can you please close this and re-open this as a feature request, I looked at the older issue you had referenced and it was categorized as a feature request.

@arthanson commented on GitHub (Apr 26, 2024): @davama can you please close this and re-open this as a feature request, I looked at the older issue you had referenced and it was categorized as a feature request.
Author
Owner

@davama commented on GitHub (Apr 26, 2024):

@arthanson
thank you for looking into

Will do

@davama commented on GitHub (Apr 26, 2024): @arthanson thank you for looking into Will do
Author
Owner

@davama commented on GitHub (Apr 26, 2024):

@arthanson
ticket created 👍

thank you!

@davama commented on GitHub (Apr 26, 2024): @arthanson ticket created :+1: thank you!
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#9539