Просмотр исходного кода

Fixes #20320: Ensure related interface options availibility in bulk edit (#21006)

Martin Hauser 1 месяц назад
Родитель
Сommit
3813aad8b1
2 измененных файлов с 48 добавлено и 5 удалено
  1. 16 0
      netbox/netbox/object_actions.py
  2. 32 5
      netbox/netbox/tests/test_object_actions.py

+ 16 - 0
netbox/netbox/object_actions.py

@@ -1,3 +1,4 @@
+from django.db.models import ForeignKey
 from django.template import loader
 from django.urls.exceptions import NoReverseMatch
 from django.utils.translation import gettext_lazy as _
@@ -175,6 +176,21 @@ class BulkEdit(ObjectAction):
     permissions_required = {'change'}
     template_name = 'buttons/bulk_edit.html'
 
+    @classmethod
+    def get_context(cls, context, model):
+        url_params = super().get_url_params(context)
+
+        # If this is a child object, pass the parent's PK as a URL parameter
+        if parent := context.get('object'):
+            for field in model._meta.get_fields():
+                if isinstance(field, ForeignKey) and field.remote_field.model == parent.__class__:
+                    url_params[field.name] = parent.pk
+                    break
+
+        return {
+            'url_params': url_params,
+        }
+
 
 class BulkRename(ObjectAction):
     """

+ 32 - 5
netbox/netbox/tests/test_object_actions.py

@@ -1,11 +1,10 @@
 from unittest import skipIf
 
 from django.conf import settings
-from django.test import TestCase
+from django.test import RequestFactory, TestCase
 
-from dcim.models import Device
-from netbox.object_actions import AddObject, BulkImport
-from netbox.tests.dummy_plugin.models import DummyNetBoxModel
+from dcim.models import Device, DeviceType, Manufacturer
+from netbox.object_actions import AddObject, BulkEdit, BulkImport
 
 
 class ObjectActionTest(TestCase):
@@ -20,9 +19,11 @@ class ObjectActionTest(TestCase):
         url = BulkImport.get_url(obj)
         self.assertEqual(url, '/dcim/devices/import/')
 
-    @skipIf('netbox.tests.dummy_plugin' not in settings.PLUGINS, "dummy_plugin not in settings.PLUGINS")
+    @skipIf('netbox.tests.dummy_plugin' not in settings.PLUGINS, 'dummy_plugin not in settings.PLUGINS')
     def test_get_url_plugin_model(self):
         """Test URL generation for plugin models includes plugins: namespace"""
+        from netbox.tests.dummy_plugin.models import DummyNetBoxModel
+
         obj = DummyNetBoxModel()
 
         url = AddObject.get_url(obj)
@@ -30,3 +31,29 @@ class ObjectActionTest(TestCase):
 
         url = BulkImport.get_url(obj)
         self.assertEqual(url, '/plugins/dummy-plugin/netboxmodel/import/')
+
+    def test_bulk_edit_get_context_child_object(self):
+        """
+        Test that the parent object's PK is included in the context for child objects.
+
+        Ensure that BulkEdit.get_context() correctly identifies and
+        includes the parent object's PK when rendering a child object's
+        action button.
+        """
+        manufacturer = Manufacturer.objects.create(name='Manufacturer 1', slug='manufacturer-1')
+        device_type = DeviceType.objects.create(manufacturer=manufacturer, model='Device Type 1', slug='device-type-1')
+
+        # Mock context containing the parent object (DeviceType)
+        request = RequestFactory().get('/')
+        context = {
+            'request': request,
+            'object': device_type,
+        }
+
+        # Get context for the child model (Device)
+        action_context = BulkEdit.get_context(context, Device)
+
+        # Verify that 'device_type' (the FK field name) is present in
+        # url_params with the parent's PK
+        self.assertIn('url_params', action_context)
+        self.assertEqual(action_context['url_params'].get('device_type'), device_type.pk)