Răsfoiți Sursa

Fixes: #20984 - Django 6.0 (#21583)

bctiemann 16 ore în urmă
părinte
comite
53ae164c75

+ 4 - 2
base_requirements.txt

@@ -4,7 +4,7 @@ colorama
 
 
 # The Python web framework on which NetBox is built
 # The Python web framework on which NetBox is built
 # https://docs.djangoproject.com/en/stable/releases/
 # https://docs.djangoproject.com/en/stable/releases/
-Django==5.2.*
+Django==6.0.*
 
 
 # Django middleware which permits cross-domain API requests
 # Django middleware which permits cross-domain API requests
 # https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst
 # https://github.com/adamchainz/django-cors-headers/blob/main/CHANGELOG.rst
@@ -35,7 +35,9 @@ django-pglocks
 
 
 # Prometheus metrics library for Django
 # Prometheus metrics library for Django
 # https://github.com/korfuri/django-prometheus/blob/master/CHANGELOG.md
 # 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
 # Django caching backend using Redis
 # https://github.com/jazzband/django-redis/blob/master/CHANGELOG.rst
 # https://github.com/jazzband/django-redis/blob/master/CHANGELOG.rst

+ 7 - 3
netbox/extras/tests/test_models.py

@@ -677,15 +677,19 @@ class ConfigContextTest(TestCase):
                 if hasattr(node, 'children'):
                 if hasattr(node, 'children'):
                     for child in node.children:
                     for child in node.children:
                         try:
                         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:
                         except AttributeError:
                             traverse(child)
                             traverse(child)
             traverse(where_node)
             traverse(where_node)
             return subqueries
             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
         # 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]
         distinct_subqueries = [sq for sq in tag_subqueries if sq.distinct]
 
 
         # Verify we found at least one DISTINCT subquery for tags
         # Verify we found at least one DISTINCT subquery for tags

+ 3 - 1
netbox/ipam/lookups.py

@@ -94,9 +94,11 @@ class NetHost(Lookup):
         rhs, rhs_params = self.process_rhs(qn, connection)
         rhs, rhs_params = self.process_rhs(qn, connection)
         # Query parameters are automatically converted to IPNetwork objects, which are then turned to strings. We need
         # 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.
         # 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:
         if rhs_params:
             rhs_params[0] = rhs_params[0].split('/')[0]
             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
         return f'HOST({lhs}) = {rhs}', params
 
 
 
 

+ 1 - 0
netbox/netbox/settings.py

@@ -435,6 +435,7 @@ INSTALLED_APPS = [
     'django.contrib.messages',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'django.contrib.staticfiles',
     'django.contrib.humanize',
     'django.contrib.humanize',
+    'django.contrib.postgres',
     'django.forms',
     'django.forms',
     'corsheaders',
     'corsheaders',
     'debug_toolbar',
     'debug_toolbar',

+ 2 - 2
requirements.txt

@@ -1,5 +1,5 @@
 colorama==0.4.6
 colorama==0.4.6
-Django==5.2.11
+Django==6.0.3
 django-cors-headers==4.9.0
 django-cors-headers==4.9.0
 django-debug-toolbar==6.2.0
 django-debug-toolbar==6.2.0
 django-filter==25.2
 django-filter==25.2
@@ -7,7 +7,7 @@ django-graphiql-debug-toolbar==0.2.0
 django-htmx==1.27.0
 django-htmx==1.27.0
 django-mptt==0.18.0
 django-mptt==0.18.0
 django-pglocks==1.0.4
 django-pglocks==1.0.4
-django-prometheus==2.4.1
+django-prometheus==2.4.0
 django-redis==6.0.0
 django-redis==6.0.0
 django-rich==2.2.0
 django-rich==2.2.0
 django-rq==3.2.2
 django-rq==3.2.2