From 53ae164c75c2e251811cf025f5926dca920f5334 Mon Sep 17 00:00:00 2001 From: bctiemann Date: Thu, 5 Mar 2026 11:36:47 -0500 Subject: [PATCH] Fixes: #20984 - Django 6.0 (#21583) --- base_requirements.txt | 6 ++++-- netbox/extras/tests/test_models.py | 10 +++++++--- netbox/ipam/lookups.py | 4 +++- netbox/netbox/settings.py | 1 + requirements.txt | 4 ++-- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/base_requirements.txt b/base_requirements.txt index 5c0fe3a75..afe67a7cd 100644 --- a/base_requirements.txt +++ b/base_requirements.txt @@ -4,7 +4,7 @@ colorama # The Python web framework on which NetBox is built # https://docs.djangoproject.com/en/stable/releases/ -Django==5.2.* +Django==6.0.* # Django middleware which permits cross-domain API requests # https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst @@ -35,7 +35,9 @@ django-pglocks # Prometheus metrics library for Django # https://github.com/korfuri/django-prometheus/blob/master/CHANGELOG.md -django-prometheus +# TODO: 2.4.1 is incompatible with Django>=6.0, but a fixed release is expected +# https://github.com/django-commons/django-prometheus/issues/494 +django-prometheus>=2.4.0,<2.5.0,!=2.4.1 # Django caching backend using Redis # https://github.com/jazzband/django-redis/blob/master/CHANGELOG.rst diff --git a/netbox/extras/tests/test_models.py b/netbox/extras/tests/test_models.py index e4cd4ff43..af673645e 100644 --- a/netbox/extras/tests/test_models.py +++ b/netbox/extras/tests/test_models.py @@ -677,15 +677,19 @@ class ConfigContextTest(TestCase): if hasattr(node, 'children'): for child in node.children: try: - if child.rhs.query.model is TaggedItem: - subqueries.append(child.rhs.query) + # In Django 6.0+, rhs is a Query directly; older Django wraps it in Subquery + rhs_query = getattr(child.rhs, 'query', child.rhs) + if rhs_query.model is TaggedItem: + subqueries.append(rhs_query) except AttributeError: traverse(child) traverse(where_node) return subqueries + # In Django 6.0+, the annotation is a Query directly; older Django wraps it in Subquery + annotation_query = getattr(config_annotation, 'query', config_annotation) # Find subqueries in the WHERE clause that should have DISTINCT - tag_subqueries = find_tag_subqueries(config_annotation.query.where) + tag_subqueries = find_tag_subqueries(annotation_query.where) distinct_subqueries = [sq for sq in tag_subqueries if sq.distinct] # Verify we found at least one DISTINCT subquery for tags diff --git a/netbox/ipam/lookups.py b/netbox/ipam/lookups.py index 45f6fd82f..693903f3f 100644 --- a/netbox/ipam/lookups.py +++ b/netbox/ipam/lookups.py @@ -94,9 +94,11 @@ class NetHost(Lookup): rhs, rhs_params = self.process_rhs(qn, connection) # Query parameters are automatically converted to IPNetwork objects, which are then turned to strings. We need # to omit the mask portion of the object's string representation to match PostgreSQL's HOST() function. + # Note: params may be tuples (Django 6.0+) or lists (older Django), so convert before mutating. + rhs_params = list(rhs_params) if rhs_params: rhs_params[0] = rhs_params[0].split('/')[0] - params = lhs_params + rhs_params + params = list(lhs_params) + rhs_params return f'HOST({lhs}) = {rhs}', params diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 90c9f8334..de741d9a3 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -435,6 +435,7 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'django.contrib.humanize', + 'django.contrib.postgres', 'django.forms', 'corsheaders', 'debug_toolbar', diff --git a/requirements.txt b/requirements.txt index cf240f3c7..04879b308 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ colorama==0.4.6 -Django==5.2.11 +Django==6.0.3 django-cors-headers==4.9.0 django-debug-toolbar==6.2.0 django-filter==25.2 @@ -7,7 +7,7 @@ django-graphiql-debug-toolbar==0.2.0 django-htmx==1.27.0 django-mptt==0.18.0 django-pglocks==1.0.4 -django-prometheus==2.4.1 +django-prometheus==2.4.0 django-redis==6.0.0 django-rich==2.2.0 django-rq==3.2.2