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

This commit is contained in:
Martin Hauser
2025-12-30 17:17:14 +01:00
committed by GitHub
parent ea5371040e
commit 3813aad8b1
2 changed files with 48 additions and 5 deletions

View File

@@ -1,3 +1,4 @@
from django.db.models import ForeignKey
from django.template import loader from django.template import loader
from django.urls.exceptions import NoReverseMatch from django.urls.exceptions import NoReverseMatch
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
@@ -175,6 +176,21 @@ class BulkEdit(ObjectAction):
permissions_required = {'change'} permissions_required = {'change'}
template_name = 'buttons/bulk_edit.html' 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): class BulkRename(ObjectAction):
""" """

View File

@@ -1,11 +1,10 @@
from unittest import skipIf from unittest import skipIf
from django.conf import settings from django.conf import settings
from django.test import TestCase from django.test import RequestFactory, TestCase
from dcim.models import Device from dcim.models import Device, DeviceType, Manufacturer
from netbox.object_actions import AddObject, BulkImport from netbox.object_actions import AddObject, BulkEdit, BulkImport
from netbox.tests.dummy_plugin.models import DummyNetBoxModel
class ObjectActionTest(TestCase): class ObjectActionTest(TestCase):
@@ -20,9 +19,11 @@ class ObjectActionTest(TestCase):
url = BulkImport.get_url(obj) url = BulkImport.get_url(obj)
self.assertEqual(url, '/dcim/devices/import/') 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): def test_get_url_plugin_model(self):
"""Test URL generation for plugin models includes plugins: namespace""" """Test URL generation for plugin models includes plugins: namespace"""
from netbox.tests.dummy_plugin.models import DummyNetBoxModel
obj = DummyNetBoxModel() obj = DummyNetBoxModel()
url = AddObject.get_url(obj) url = AddObject.get_url(obj)
@@ -30,3 +31,29 @@ class ObjectActionTest(TestCase):
url = BulkImport.get_url(obj) url = BulkImport.get_url(obj)
self.assertEqual(url, '/plugins/dummy-plugin/netboxmodel/import/') 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)